如何在Rails 4中迭代单行中的关系?

时间:2016-07-12 20:03:19

标签: ruby-on-rails

我有一个User模型has_many :tasks并想做这样的事情:

 User.find([100,97]).tasks.each { |task| puts task.id }

但这似乎没有用。我试过了

 User.find([100,97]).map(&:tasks).each { |task| puts task.id }
 User.find([100,97]).each.tasks.each { |task| puts task.id }

这可能吗?我该怎么做?

2 个答案:

答案 0 :(得分:3)

喜欢这个吗?

Task.joins(:user).where("users.id" => [100, 97]).each { |task| puts task.id }

答案 1 :(得分:1)

@lusketeer说了什么,但没有必要加入:

Task.where(user: [100, 97]).each { |task| puts task.id }

它不适用于您的第一个示例的原因是find方法返回一个数组,而不是ActiveRecord::Relation,因此您无法链接任何更多的关系方法(例如,tasks)结果。

你的第二个例子,

User.find([100,97]).map(&:tasks).each { |task| puts task.id }

会起作用但不完全符合您的预期。 map(&:tasks)返回二维任务数组。每个顶级元素都包含一个包含特定用户任务的数组。要使此代码正常工作,您需要展平数组:

User.find([100,97]).map(&:tasks).flatten.each { |task| puts task.id }

虽然效率不高,但它会有效,因为它对每个用户的任务进行单独查询,使其成为N+1情况。

你的最后一个例子,

User.find([100,97]).each.tasks.each { |task| puts task.id }

也可以起作用,这只是语法问题:

User.find([100,97]).each do |user|
  user.tasks.each { |task| puts task.id }
end

这也是N+1查询的情况,因此它并不完美。