如何定义一个named_scope来使用嵌套模型汇总has_many?

时间:2010-02-02 20:27:51

标签: ruby-on-rails activerecord associations has-many

首先是数据模型:

class Forum < ActiveRecord::Base
  has_many :topics, :dependent => :destroy, :order => 'created_at desc'
end

class User < ActiveRecord::Base
  has_many :topics, :dependent => :destroy
  has_many :comments, :dependent => :destroy
  has_many :replies, :dependent => :destroy
end

class Topic < ActiveRecord::Base
  belongs_to :forum
  belongs_to :user
  has_many :comments, :dependent => :destroy
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :topic
  has_many :replies, :dependent => :destroy
end

class Reply < ActiveRecord::Base
  belongs_to :user
  belongs_to :comment
end

因此,用户可以将主题发布到论坛。他们也可以发表评论  论坛主题。他们可以发表回复评论。

我希望能够获得他们参与过的论坛列表  发布主题或评论或回复。

1 个答案:

答案 0 :(得分:0)

您正在寻找的是论坛模型中的named scope

通过在论坛模型中为评论和回复模型添加has_many:through关系,可以大大简化联接。但是我永远不会记得嵌套连接是如何工作的,所以我发布了一个可以解决你的问题的解决方案。

class Forum < ActiveRecord::Base
  has_many :topics, :dependent => :destroy, :order => 'created_at desc'
  named_scope :user_posted, lambda {|user|
    { :joins => "JOIN topics t ON t.forum_id = forums.id " +
        "JOIN comments c ON c.topic_id = t.id " +
        "JOIN replies r ON r.comment_id = c.id", 
      :conditions => ["t.user_id = ? OR c.user_id = ? OR r.user_id = ?", 
        user, user, user], 
      :group => "forums.id"
    }
  }
end

现在...

Forum.user_posted(@user)

将返回用户发布主题,回复或评论的论坛数组。

有关特定用户发布的论坛列表:

class User < ActiveRecord::Base
  has_many :topics, :dependent => :destroy
  has_many :comments, :dependent => :destroy
  has_many :replies, :dependent => :destroy    
  named_scope :posted_in_forum, lambda {|forum|
    { :joins => "JOIN replies r ON r.user_id = users.id "+
        "JOIN comments c ON c.user_id = users.id OR c.id = r.comment_id " +
        "JOIN topics t ON t.user_id = users.id OR t.id = c.topic_id " +
        "JOIN forums f ON t.forum_id = forums.id ",
      :conditions => ["f.id = ?", forum], 
      :group => "users.id"
    }
  }
end

假设我说得对,这句话:

User.posted_in_forum(@forum)

将返回按主题,评论或回复在论坛中发布的用户列表。

P.S。允许在此模型中销毁用户可能不是一个好主意。您放弃的方式,如果用户被销毁,他们发布的任何主题,回复或评论也将被删除。相反,您的用户应该停用。