我怎么能实现以下?我有两个模型(博客和读者)和参加表,这将允许我有个N:M之间的关系:

class Blog < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :readers, :through => :blogs_readers
end

class Reader < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :blogs, :through => :blogs_readers
end

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader
end

什么我现在要做的,就是添加的读者不同的博客。条件,虽然是我可以仅仅增加一个读到博客一次。所以也不能被任何重复(一样 readerID, ,同 blogID)在 BlogsReaders 表。我如何可以实现这一目标?

第二个问题是,如何获得一个名单的博客的读者不是订阅已经(例如填写一下选择清单,然后可以用来增加读者的另一个博客)?

有帮助吗?

解决方案

约什么:

Blog.find(:all,
          :conditions => ['id NOT IN (?)', the_reader.blog_ids])

Rails的负责IDS的收集我们与关联方法! :)

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ ClassMethods.html

其他提示

简单的解决方案,是内置到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博客和读者之间,除非你有你想对加盟模式的一些其他属性(你不这样做,目前)。该方法也有一个:uniq opiton。

请注意,这并不妨碍你创建的表中的条目,但它确实保证当你查询集合你只有每个对象之一。

<强>更新

在轨道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

这应该把你的第一个问题的护理:

class BlogsReaders < ActiveRecord::Base
  belongs_to :blog
  belongs_to :reader

  validates_uniqueness_of :reader_id, :scope => :blog_id
end

<强> Rails的5.1方式

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

答案在这一链接表示了如何复盖"<<"方法来实现你在找什么没有提出例外情况或创建一个单独的方法: 轨成语,以避免重复在has_many:通过

我想有人会比这更好的答案一起去。

the_reader = Reader.find(:first, :include => :blogs)

Blog.find(:all, 
          :conditions => ['id NOT IN (?)', the_reader.blogs.map(&:id)])

[编辑]

请参见下面乔希的答案。这是要走的路。 (我知道有一种更好的方式在那里;)

在顶部答案目前说在proc使用uniq

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { uniq }, through: :blogs_readers
end

此然而踢关系到一个数组,可以打破东西,期待对的关系进行操作,而不是阵列。

如果您使用distinct它保持它作为一个关系:

class Blog < ActiveRecord::Base
 has_many :blogs_readers, dependent:  :destroy
 has_many :readers,  -> { distinct }, through: :blogs_readers
end

最简单的方法是序列的关系到一个数组:

class Blog < ActiveRecord::Base
  has_many :blogs_readers, :dependent => :destroy
  has_many :readers, :through => :blogs_readers
  serialize :reader_ids, Array
end

然后向读者分配值时,在应用它们作为

blog.reader_ids = [1,2,3,4]

当分配关系这种方式,重复被自动删除。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top