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
选项。
请注意,这不会阻止您在表中创建条目,但它确实确保当您查询集合时,您只能获得每个对象中的一个。
更新
在 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