web-dev-qa-db-ja.com

has_many:through:uniq in Rails 4を使用する場合の非推奨の警告

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宣言を書き換える正しい方法は何ですか?

95
BoosterStage

uniqオプションは、スコープブロックに移動する必要があります。スコープブロックはhas_manyの2番目のパラメーターである必要があることに注意してください(つまり、行の最後に残すことはできません。: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
236
Dylan Markow

Dylansの答えに加えて、モジュールとの関連付けを拡張する場合は、次のように、(個別に指定するのではなく)スコープブロックで連鎖させてください。

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

たぶん私だけかもしれませんが、スコープブロックを使用してアソシエーションプロキシを拡張することは非常に直感的ではないようです。

5
Andrew Hacking