1. ホーム
  2. ruby-on-rails

[解決済み] has_many through リレーションシップからユニークなレコードを表示するには?

2022-05-16 15:53:26

質問

Rails3でhas_many, throughリレーションからユニークなレコードを表示するのに最適な方法は何でしょうか。

私は3つのモデルを持っています。

class User < ActiveRecord::Base
    has_many :orders
    has_many :products, :through => :orders
end

class Products < ActiveRecord::Base
    has_many :orders
    has_many :users, :through => :orders
end

class Order < ActiveRecord::Base
    belongs_to :user, :counter_cache => true 
    belongs_to :product, :counter_cache => true 
end

例えば、顧客が注文したすべての製品を、顧客のショーページにリストアップしたいとします。

彼らはいくつかの製品を複数回注文しているかもしれません。そこで、counter_cacheを使用して、注文数に基づいて降順で表示するようにしています。

しかし、複数回注文している場合、各商品が一度だけ表示されるようにする必要があります。

@products = @user.products.ranked(:limit => 10).uniq!

は、1つの商品に対して複数の注文記録がある場合に動作しますが、1度しか注文されていない場合はエラーが発生します。(ランクは別の場所で定義されたカスタムソート関数です。)

もう一つの代替案は

@products = @user.products.ranked(:limit => 10, :select => "DISTINCT(ID)")

このアプローチでいいのか自信がない。

この問題に取り組まれた方はいらっしゃいますか?どのような問題に直面しましたか?.unique!とDISTINCT()の違いについて、どこでもっと知ることができますか?

has_many、throughの関係を通してユニークなレコードのリストを生成するための最良の方法は何ですか?

ありがとうございます。

どのように解決するのですか?

has_manyの関連付けに:uniqオプションを指定してみましたか?

has_many :products, :through => :orders, :uniq => true

から Railsのドキュメント :

<ブロッククオート

:uniq

true の場合、コレクションから重複が省かれる。throughと組み合わせて使うと便利です。

rails 4 用に更新しました。

Rails 4では has_many :products, :through => :orders, :uniq => true は非推奨です。代わりに、現在は has_many :products, -> { distinct }, through: :orders . 参照 ActiveRecord Associations documentationのhas_many::throughのリレーションシップのための明確なセクションを参照してください。 を参照してください。 コメントで指摘してくれたKurt Muellerに感謝します。