Reputation: 1698
In a conversation controller, I have the following:
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)))
@users = @users.search(params[:query]) if params[:query].present?
@users = sort_and_paginate(@users)
set_meta_tags title: "Existing Conversations", reverse: true
end
Inside the user model, I have this has_many
relaitonship:
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
Inside the controller model, I have the belongs_to
association:
belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'
Back to the controller, the @users
object is being rendered to the view. I need an additional column from the conversation table which is the last_updated
column.
So basically I want to add a key value pair to @users
from the conversation
table
I've tried things like
@users.each do |user|
user[:latest_conversation] = Conversation.where(sender_id: user.id)
end
which results in can't write unknown attribute latest_conversation
I've also tried to do a test query like
@testUsers = @users.sender_conversations
Which results in undefined method sender_conversations
As you can see above, I have the associations in my model. The docs show examples and I thought this would work
In my view I have:
<% @users.each do |user| %>
<tr class="table__row" onclick="window.location.href = '/conversations?user_id=<%= user.id %>'">
<td><%= user.name %></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 %></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 %>
So i'd really like a way to access @user.latest_conversation
inside the users loop
Upvotes: 0
Views: 1965
Reputation: 6603
class User < ApplicationRecord
# ...
# combines both "sender" and "recipient" conversations
# you can also move this into a `has_many :conversations` but you'll need
# to `unscope`; see @dre-hh answer here https://stackoverflow.com/questions/24642005/rails-association-with-multiple-foreign-keys
def conversations
Conversation.where(sender_id: id).or(
Conversation.where(recipient_id: id)
)
end
## instead of above, try the commented code below
## Untested, but I think this should also work
# def conversations
# sender_conversations.or(recipient_conversations)
# end
# get the latest conversation ordered by "last_updated"
def latest_conversation
conversations.order(last_updated: :desc).first
end
end
Upvotes: 1
Reputation: 15838
Why don't you define a method on the User model?
class User < ...
def latest_conversation
sender_conversations.last
end
Upvotes: 1