Rails に組み込まれているより単純なソリューション:
class Blog < ActiveRecord::Base
has_many :blogs_readers, :dependent => :destroy
has_many :readers, :through => :blogs_readers, :uniq => true
end
class Reader < ActiveRecord::Base
has_many :blogs_readers, :dependent => :destroy
has_many :blogs, :through => :blogs_readers, :uniq => true
end
class BlogsReaders < ActiveRecord::Base
belongs_to :blog
belongs_to :reader
end
呼び出しに:uniq => true
オプションを追加することに注意してください。has_many
またhas_and_belongs_to_many
、結合モデルで使用したい他の属性がない限り (現在は使用していません)、Blog と Reader の間で検討することをお勧めします。そのメソッドにはオプションもあり:uniq
ます。
これにより、テーブルにエントリを作成できなくなるわけではありませんが、コレクションに対してクエリを実行すると、各オブジェクトが 1 つだけ取得されるようになります。
アップデート
Rails 4 では、これを行う方法はスコープ ブロックを使用することです。上記は に変わります。
class Blog < ActiveRecord::Base
has_many :blogs_readers, dependent: :destroy
has_many :readers, -> { uniq }, through: :blogs_readers
end
class Reader < ActiveRecord::Base
has_many :blogs_readers, dependent: :destroy
has_many :blogs, -> { uniq }, through: :blogs_readers
end
class BlogsReaders < ActiveRecord::Base
belongs_to :blog
belongs_to :reader
end
Rails 5 のアップデート
uniq
スコープ ブロック で を使用すると、エラーが発生しますNoMethodError: undefined method 'extensions' for []:Array
。distinct
代わりに使用してください:
class Blog < ActiveRecord::Base
has_many :blogs_readers, dependent: :destroy
has_many :readers, -> { distinct }, through: :blogs_readers
end
class Reader < ActiveRecord::Base
has_many :blogs_readers, dependent: :destroy
has_many :blogs, -> { distinct }, through: :blogs_readers
end
class BlogsReaders < ActiveRecord::Base
belongs_to :blog
belongs_to :reader
end