我有些复杂的设置。
我正在查询具有消息线程(Conversations
)的所有用户。
我的用户模型在has_many
中的两列上具有Conversation
关系
has_many :sender_conversations, class_name: 'Conversation', foreign_key: "sender_id", dependent: :destroy
has_many :recipient_conversations, class_name: 'Conversation', foreign_key: "recipient_id", dependent: :destroy
我需要一种获取最新对话的方法,因为任何用户都可以有多个线程。
为了实现这一点,我在用户模型上具有以下方法:
def conversations
sender_conversations.or(recipient_conversations)
end
def latest_conversation
conversations.order(updated_at: :desc).first
end
会话模型:
class Conversation < ApplicationRecord
...
belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
...
validates :sender_id, uniqueness: { scope: [:recipient_id, :property_id] }
scope :between, ->(sender_id, recipient_id) do
where(sender_id: sender_id, recipient_id: recipient_id).or(
where(sender_id: recipient_id, recipient_id: sender_id)
)
end
...
控制器操作正在查询具有sender_id
或recipient_id
的用户
def users_with_existing_conversations
authorize! :users_with_existing_conversations, Conversation
@users = User.accessible_by(current_ability, :index_conversations)
@users = @users.where(id: Conversation.select(:sender_id))
.or(@users.where(id: Conversation.select(:recipient_id)))
...
end
然后,最后,在视图中,我正在循环通过
<% @users.each do |user| %>
<tr class="table__row" onclick="window.location.href = '/conversations?user_id=<%= user.id %>'">
<td><%= user.name %>(<%= user.id %>)</td>
<td><%= user.surname %></td>
<td><%= user.email %></td>
<td><%= user.company_name.present? ? user.company_name : "N/A" %></td>
<td><%= user.role.capitalize %></td>
<td><%= user.created_at.try(:strftime, '%b %d, %Y') %></td>
<td><%= user.latest_conversation.updated_at.localtime.strftime('%b %d, %Y at %l:%M %p') %></td>
<td class="table__more">
<%= link_to "Show details", conversations_path(user_id: user.id), class: 'table__row__details button button--tertiary button--tertiary-small' %>
</td>
</tr>
<% end %>
现在我不知道如何通过latest_conversation
列即updated_at
对这些行进行排序。
所以我有一个要查询的用户表,但是我想通过他们与会话表的updated_at
列的关系来排序查询。
您可以使用INNER JOIN
子句尝试使用自定义IN
来检查两个conversations
'列:
User.joins('INNER JOIN conversations c ON users.id IN (c.sender_id, c.recipient_id)')
.order('c.created_at')