我正在尝试为我的项目编写一个Messagecenter。
我遇到的问题是我只想显示来自用户的最后一条消息,将显示最后一条消息。
表的ID为Sender_ID,Receiver_ID和MessageTXT。
到现在为止我已经使用过:
@messages = Message.find_by_sql("select * from messages where id IN(SELECT MAX( id ) FROM messages WHERE sender_id = #{current_user.id} OR receiver_id = #{current_user.id} GROUP BY sender_id, receiver_id )")
它给了我最后一条消息和来自不同用户的最后一条消息。
答案 0 :(得分:3)
您应该可以使用已命名的scope
来执行此操作,而不必使用find_by_sql
,这实际上是最后的工具。
示例:
class Message < ActiveRecord::Base
scope :for_user, lambda { |user_id|
where([ 'sender_id=? OR receiver_id=?', user_id, user_id)
}
end
使用此功能,您可以检索最后一个:
@last_message = Message.for_user(user_id).order('id DESC').first
这应该生成类似于您定义的查询。
答案 1 :(得分:0)
我认为您查询的问题是您忘记指定订单而忘记指定“LIMIT 1”。你应该看看tadman的答案,以便更好地做到这一点。
答案 2 :(得分:0)
Message.where("sender_id = :user_id OR receiver_id = :user_id", {:user_id => current_user.id}).order('created_at').last
这应创建一个SQL请求,列出您的用户是发件人或收件人的所有邮件,按创建日期对其进行排序,并为您提供最后一个。
我已经使用创建日期而不是id对消息进行了排序,因为数据库可能不会使用自动增量ID。考虑在created_at
列上添加索引以提高效率。
同样避免在SQL请求中使用“#{...}”,特殊字符可能无法正确处理,并且容易受到SQL注入。
答案 3 :(得分:0)
@messages = Message.find_by_sql("select * from messages
WHERE sender_id = #{current_user.id} OR receiver_id = #{current_user.id}")
或者您无需使用find_by_sql
,您可以将其作为
@messages = Message.find(:all, :conditions => ["sender_id = ? or
receiver_id = ?", current_user.id, current_user.id]);
这将返回由id排序的匹配条件数组。默认情况下,id是自动创建并递增的,因此最后一条消息将具有最高ID,因此您可以获得最后一条消息,如下所示
@last_message = @messages.last