0

i am trying to access some nested attributes in a rails partial; let me explain my issue:

i wrote a simple messaging service according to the tutorial of dana mulder i mentioned in another question of mine. a user has_many conversations, and a conversation has_many messages. every conversation has a recipient and a sender and every message has a boolean read, which is set to false by default.

what i am trying to do is to write a simple function that iterates through every message a user got in a conversation he is involved in, checks if the last message a user recieved in a conversation is read == true and not send by himself to display a little knob beside the "messages" link in the navigation of my app.

What i basically want to check is (multiple lines for better readability):

<%= if current_user.conversations.all.messages.last.user_id != current_user.id && current_user.conversations.all.messages.last.read == false %>

    Message link with bubble beside it

<% else %>

    Message link

<% end %>

This syntax does not work .. How is it possible to iterate through every conversation a user is involved, check the last message of every conversation if its written by this user and if not if its already read?

while something like Conversation.last.messages.last.content is working, current_user.conversations.all.messages.last.content is not.. i find it a bit confusing how the accessibility of rails models are working.

thanks in advance! i hope i was explaining me well enough.

Best Regards

2
  • Is there a separate Message link for each conversation? Or just one for all conversations? Commented Sep 18, 2018 at 16:50
  • I guess you need to loop through each conversation. "conversations.all.messages" won't work as "conversations.all" would return an active relation object. ( On a side note using "all" should be avoided if there are many conversations. It will load all the conversations into memory causing high memory usage ) Commented Sep 18, 2018 at 16:56

1 Answer 1

1

What are you trying to do with current_user.conversations.all.messages.last.content? because conversations.all is an association, it is NOT a Conversation, so messages is not an available method. Conversation.last IS a Conversation, that's why you can call messages on it.

You can try current_user.conversations.last.messages.last.content to get the last message of the last conversation, or, you can use a "has_many :through" relationship on User

class User ...
  has_many :conversations
  has_many :messages, through: :conversations
end

That way you can do current_user.messages if you want ALL user's messages and current_user.messages.last to get the last Message (even if it's not from the last conversation).

I'd recommend you to read the Rails Guide about Associations https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

EDIT: To know if the user has some unread message, you can use the has_many :through association and do something like

current_user.messages.where(read: false).where.not(user_id: current_user.id).any?

That will return true any message from the user's conversations with id != current_user.id is not read. And false otherwise.

You can use count instead of any? if you wan't to know the actual number of unread messages.

Sign up to request clarification or add additional context in comments.

10 Comments

I don't think this will meet OP's intention. If conversation 1 last message is from someone else and is unread but conversation 2 last message is from himself, he won't know there's a conversation where he hasn't seen the latest messages.
@SteveTurczyn, that's why I asked what is he trying to do with the line with invalid syntax, I was just clarifying why the syntax is wrong and a few ways to fix that but it was not clear for me what was his intention
Thanks for the fast response. SteveTurczyn is right. The line with „.content“ was just to gibe an example that the one is working and the other is not. Instead ive should have wrote „.read“. I want to check if any of the messages of a conversation the current user is involved with, he is not the author of is read or not to display a hint that there is a new message. But since its in a partial im not able to access the „.read“ boolean-values easily.
@GabrielTheCoder, check my edit, with the has_many :through association you can query the messages to know if there's any message from a user other than current_user which is read=false.
@arieljuod that fixed a bit of the headache, thanks for this. but now i have to iterate through the messages without displaying them. ill write some more tomorrow if my brain is cleared
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.