2009-08-27 2 views
0

В типичной модели User-Post-Comment в Rails каждый пользователь может создать сообщение, а также создать комментарий. Вопрос заключается в том, как захватить каждый пользовательский последний комментарий к определенному сообщению.Возьмите только последний комментарий в Rails

Example: 

Post A have 3 user making comment 
User 1 have comment 1, 2, 3, 4, 5, 6 
User 2 have comment 1, 2, 3, 4 
User 3 have comment 1, 2 

Так вид, что я хочу только последний комментарий для каждого пользователя:

Post A have 3 user making comment 
User 1 latest comment that is 6 
User 2 latest comment that is 4 
user 3 latest comment that is 2 

Как это сделать?

благодаря

+0

Итак, когда сообщение А имеет 3 пользователей, вы говорите, что сообщение модели пользователи has_many, или что он has_many комментарии который, в свою очередь, принадлежит пользователю? – Matchu

+0

У пользователя много сообщений и комментариев, Post имеет много комментариев и принадлежит пользователю, Комментарий принадлежит к сообщению и принадлежит пользователю – gkrdvl

ответ

1

Что-то вроде этого:

post.comments.for_user(current_user).last 

добавить named_scope в модели

class Comment 
    named_scope :for_user, lambda{ |user| {:conditions=>{:user_id => user.id}} 
end 

Это должно сделать трюк.

Если вы предпочитаете делать это в рельсах,

messages_by_users = post.messages.group_by(&:user) 

messages_by_users.each do |key, value| 
    messages_by_users[key] = value.last 
end 
+0

. Интересно, есть ли способ для одного запроса для выполнения этой работы, если вы хотите отобразить последний комментарий для все 3 пользователя ... – Matchu

+0

Matchu, я добавил решение rails для загрузки запроса только один раз - путем загрузки всех комментариев в память), интересно, есть ли другие способы использования SQL –

+0

@ez, первое решение только захватит current_user последним комментарий, как захватить другой? – gkrdvl

0

Я должен был получить этот вид данных и обычно я в конечном итоге делает два запроса. В моем случае у меня есть блоги и их сообщения, и мне нужен список из 3 последних сообщений в блоге с ограничением, что блоги уникальны, я не хочу 2 сообщения из того же блога. Я закончил тем, что делал что-то вроде этого (MySQL):

q = <<-EOQ 
SELECT id,pub_date FROM 
    (
    SELECT id,blog_id,pub_date 
    FROM posts 
    ORDER BY pub_date DESC 
    LIMIT 40 
) 
t 
GROUP BY blog_id 
ORDER BY pub_date DESC 
LIMIT #{num_posts} 
EOQ 
post_ids = Post.connection.select_values(q) 
Post.find(:all, :include => [:blog], :conditions => ["id IN (?)", post_ids], :order => "posts.pub_date DESC")  

Так что в вашем случае, если вы могли бы иметь что-то вроде:

q = <<-EOQ 
SELECT id FROM 
    (
    SELECT id,post_id 
    FROM comments 
    ORDER BY id DESC 
    LIMIT 40 
) 
t 
GROUP BY post_id 
ORDER BY id DESC 
LIMIT 10 
EOQ 
post_ids = Post.connection.select_values(q) 
Post.find(:all, :include => [:blog], :conditions => ["id IN (?)", post_ids], :order => "posts.id DESC") 
0

Предполагая, что база данных является присвоение последовательных идентификаторов комментариев, вы можете сделать это:

class Comment 
    named_scope :most_recent, lambda { 
    lastest_comments = Comment.maximum :id, :group => "user_id, post_id" 
    { :conditions => [ "comment_id in ?", lastest_comments.map(&:last) ] } 
    } 
end 

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

Как она стоит, это гибкий метод, который позволяет выполнить следующие действия:

Comment.most_recent.find_by_user @user #-> the most recent comments on all posts by a user 
@user.comments.most_recent    #-> same as above 

Comment.most_recent.find_by_post @post #-> the most recent comments on a single post by all users 
@post.comments.most_recent    #-> same as above 

Comment.most_recent.find_by_user_and_post @user, @post #-> the specific most recent comment by a certain user on a certain post 
@post.comments.most_recent.find_by_user @user    #-> you get the idea 
Смежные вопросы