ActiveRecord关系实践

时间:2013-11-18 19:12:33

标签: ruby-on-rails ruby activerecord

我有以下型号:

class Foo < ActiveRecord::Base
  attr_accessible :name, headline
end

class Unit < ActiveRecord::Base
  attr_accessible :title, :bar
  has_many :sites
  has_many :articles, :through => :sites
  belongs_to :foo
end

class Site < ActiveRecord::Base
  attr_accessible :article_id
  belongs_to :unit
  belongs_to :article
end

class Article < ActiveRecord::Base
  attr_accessible :title
  has_many :sites
  has_many :units, :through => :sites
end

现在foos_controller我得到了foo的单位:

class FoosController < ApplicationController
  #...
  units = Unit.where(:foo_id => params[:foo_id])
  # Now here I want to set each unit title with its site.article.title
end

如何设置unit.title及其site.article.title

2 个答案:

答案 0 :(得分:1)

根据您的说明,Unit似乎有一个Site - 所以您需要添加该关联:

class Unit < ActiveRecord::Base
  attr_accessible :title, :foo
  has_one :site
  belongs_to :foo
end

现在你可以这样做:

units = Unit.where(:foo_id => params[:foo_id]).includes(:articles)
units.each do |unit| 
   unit.update_attributes(title: unit.articles.first.title)
end

请注意在原始查询中使用includes。当您遍历单元时,这将急切地加载必要的文章以避免N + 1查询问题。

请注意,此方法假设您每个单元的文章数量不多。如果你这样做了,就需要进行调整以避免不必要地加载太多文章。

答案 1 :(得分:0)

根据您使用的语法并基于它具有article_id的事实,网站看起来也应该belongs_to :article。除非您明确希望更改attr_accessible :article_id,否则您可以删除belongs_to :article。然后,您就可以致电unit.title = site.article.title(或者您可以使用unit.update_attribute('title',site.article.title)