加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 在Rails关系上使用Ruby的select方法并更新它

发布时间:2020-12-17 03:22:57 所属栏目:百科 来源:网络整理
导读:我有一个用户之前“投票”的ActiveRecord关系… @previous_votes = current_user.votes 我需要将这些内容过滤到目前的“挑战”,所以Ruby的select方法似乎是最好的方法… @previous_votes = current_user.votes.select { |v| v.entry.challenge_id == Entry.f
我有一个用户之前“投票”的ActiveRecord关系…

@previous_votes = current_user.votes

我需要将这些内容过滤到目前的“挑战”,所以Ruby的select方法似乎是最好的方法…

@previous_votes = current_user.votes.select { |v| v.entry.challenge_id == Entry.find(params[:entry_id]).challenge_id }

但我还需要更新这些记录的属性,select方法将我的关系转换为无法更新或保存的数组!

@previous_votes.update_all :ignore => false
# ...
# undefined method `update_all' for #<Array:0x007fed7949a0c0>

如何像select方法那样过滤我的关系,但是不能失去用ActiveRecord更新/保存项目的能力?

在Google周围看来,似乎named_scope出现在类似问题的所有答案中,但我无法弄清楚它们能否专门完成我所追求的目标.

解决方法

问题是select不是SQL方法.它获取所有记录并在Ruby端过滤它们.这是一个简化的例子:

votes = Vote.scoped
votes.select{ |v| v.active? }
# SQL: select * from votes
# Ruby: all.select{ |v| v.active? }

由于update_all是一个SQL方法,因此无法在Ruby数组中使用它.您可以坚持在Ruby中执行所有操作或将其中的一些(全部)移动到SQL中.

votes = Vote.scoped
votes.select{ |v| v.active? }
# N SQL operations (N - number of votes)
votes.each{ |vote| vote.update_attribute :ignore,false }
# or in 1 SQL operation
Vote.where(id: votes.map(&:id)).update_all(ignore: false)

如果你实际上没有使用获取的投票,那么执行整个选择和放大会更快. SQL端更新:

Vote.where(active: true).update_all(ignore: false)

虽然前面的示例适用于您的选择,但这个示例要求您根据SQL重写它.如果您在Rails模型中设置了所有关系,则可以大致如下:

entry = Entry.find(params[:entry_id])
current_user.votes.joins(:challenges).merge(entry.challenge.votes)
# requires following associations:
# Challenge.has_many :votes
# User.has_many :votes
# Vote.has_many :challenges

Rails将为您构建适当的SQL.但是,如果某些东西不起作用,你总是可以回过头来编写SQL.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读