Как определить named_scope, чтобы свернуть has_many с вложенными моделями? - PullRequest
1 голос
/ 02 февраля 2010

Первая модель данных:

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 голосов
/ 02 февраля 2010

То, что вы ищете, это именованная область действия в модели форума.

Объединение можно значительно упростить, добавив has_many: через связи для ваших моделей комментариев и ответов в модели форума. Но я никогда не могу вспомнить, как работают вложенные объединения, поэтому я опубликовал решение, которое будет работать с тем, что у вас есть.

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. Вероятно, не стоит разрешать уничтожение пользователей в этой модели. То, как вы выложили вещи, если пользователь будет уничтожен, любые темы, ответы или комментарии, которые он опубликовал, также будут удалены. Вместо этого ваши пользователи должны быть деактивированы.

...