Можно ли смотреть за собой в self.posts.find? - PullRequest
1 голос
/ 24 мая 2009

Расширяя страницу недавних_постов_on_self ниже, Я хочу добавить метод all_recent_posts_on_self , но я не уверен, возможно ли с использованием синтаксиса self.posts.find . С другой стороны, all_recent_posts_on_class кажется простым.

class User < ActiveRecord::Base
  has_many :posts, :class_name => "Post" , :foreign_key => "author_id"
  has_many :comments, :class_name => "Comment", :foreign_key => "author_id"

  def recent_posts_on_class
    Post.find(  :all, :conditions => ['author_id = ?', self.id],
                :order => 'created_at asc', :limit => 5)
  end

  def recent_posts_on_self
    self.posts.find(:all, :order => 'created_at ASC', :limit => 5)
  end
end

В приведенном выше примере у меня есть два способа найти последние сообщения в блоге, связанные с пользователем. Я могу позвонить в Post.find и передать его author_id, или я могу вызвать self.posts.find, и мне не нужно передавать идентификатор автора. Я предполагаю, что это связано с тем, что в последнем случае self.posts уже был ограничен на основе первичного ключа объекта пользователя и has_many: сообщений, связанных с этим пользователем. Это преимущество в этом случае, потому что мне не нужно переходить к проблеме передачи author_id в качестве аргумента. Но если бы мне не нужно было ограничивать запрос по автору, можно ли было бы создать all_recent_posts_on_self для этого?

То, о чем я говорю, является эквивалентом этого метода (который пропускает: условия):

  def all_recent_posts_on_class
    Post.find(:all, :order => 'created_at asc', :limit => 5)
  end

Но с использованием self.posts.find вместо Post.find :

  def all_recent_posts_on_self
    self.posts.find(...)
  end

Также:

Даже если для этого можно использовать self.posts.find, лучше ли использовать Post.find?

Ответы [ 2 ]

4 голосов
/ 24 мая 2009

Это не совсем то, что вы просили, но я считаю, что это полезно знать, и следование общим шаблонам помогает избежать сложных или запутанных реализаций.

"Путь Rails" для этого заключается в использовании именованных областей:

class Post < ActiveRecord::Base
  belongs_to :user
  named_scope :recent, :order => 'created_at desc', :limit => 5
end

class User < ActiveRecord::Base
  has_many :posts
end

Это не становится намного более декларативным и легко читаемым, чем это:

user.posts.recent # 5 most recent posts by the user
Post.recent # 5 most recent posts globally
1 голос
/ 24 мая 2009

Я не уверен, почему вы захотите использовать self.posts.find (..) для поиска сообщений других авторов. Эта идиома предназначена специально для поиска подмножества объектов, связанных с конкретным экземпляром.

Post.find () - это то, что вы должны использовать, когда не хотите ограничивать конкретную модель пользователя. В конце концов, метод posts () на объекте User был просто удобством, которое фактически совпадает с (кэшированным) вызовом Post.find (: all,: condition => ['author_id', self.id]).

...