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

97
Rails 4在使用has_many :through时,使用:uniq => true会出现弃用警告。例如:
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 声明?

2个回答

240

uniq选项需要移动到作用域块内。请注意,作用域块需要成为has_many的第二个参数(即不能将其留在行末,需要在:through => :donations之前移动):

uniq选项需要移动到作用域块内。请注意,作用域块需要成为has_many的第二个参数(即不能将其留在行末,需要在:through => :donations之前移动):

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

这可能看起来很奇怪,但如果您考虑有多个参数的情况,它会更有意义。例如:

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

变成:

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

谢谢,这个很有效!你在哪里找到的?我在文档中没能找到它。 - Ryenski
6
我在《升级到Rails 4》这本书中(目前还在进行中)看到了它:http://www.upgradingtorails4.com/ -- 没有在其他地方找到过。 - Dylan Markow
1
@DylanMarkow 升级到Rails 4的链接已失效。该书现在已根据CC许可发布在https://github.com/alindeman/upgradingtorails4下。 - Ivar
1
使用Rails 5时,使用distinct而不是uniq。更多详情请参阅此答案 - Nic Nilov

5
除了Dylan的答案之外,如果您要扩展模块的关联,请确保在作用域块中链接它(而不是单独指定),如下所示:
has_many :donors,
  -> { extending(DonorExtensions).order(:name).uniq },
  through: :donations

也许只是我个人的看法,但使用作用域块来扩展关联代理似乎非常不直观。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接