在 Rails 4中使用 has_many: through: uniq 时的弃用警告

Rails 4在使用: uniq = > true 和 has _ many: through 时引入了一个弃用警告:

has_many :donors, :through => :donations, :uniq => true

产生以下警告:

DEPRECATION WARNING: The following options in your Goal.has_many :donors declaration are deprecated: :uniq. Please use a scope block instead. For example, the following:


has_many :spam_comments, conditions: { spam: true }, class_name: 'Comment'


should be rewritten as the following:


has_many :spam_comments, -> { where spam: true }, class_name: 'Comment'

重写上述 has _ many 声明的正确方法是什么?

23119 次浏览

The uniq option needs to be moved into a scope block. Note that the scope block needs to be the second parameter to has_many (i.e. you can't leave it at the end of the line, it needs to be moved before the :through => :donations part):

has_many :donors, -> { uniq }, :through => :donations

It may look odd, but it makes a little more sense if you consider the case where you have multiple parameters. For example, this:

has_many :donors, :through => :donations, :uniq => true, :order => "name", :conditions => "age < 30"

becomes:

has_many :donors, -> { where("age < 30").order("name").uniq }, :through => :donations

In addition to Dylans answer, if you happen to be extending the association with a module, make sure that you chain it in the scope block (as opposed to specifying it separately), like so:

has_many :donors,
-> { extending(DonorExtensions).order(:name).uniq },
through: :donations

Maybe its just me but it seems very unintuitive to use a scope block to extend an association proxy.