Reputation: 3120
I'm working on a Ruby on Rails based chat. So I initially create a conversation between 2 clients when they add each other as friends and my model for Conversation
is as follows:
class Conversation < ActiveRecord::Base
has_many :messages
belongs_to :player_client
belongs_to :client
end
Now when the player_client
clicks a specific button I want to create an automated message for them. This should only happen if they've never sent a message to each other i.e. the conversation has no associated messages.
Trying the following methods from the console:
@conversation = Conversation.find(7)
@conversation.messages.any?
> False
@conversation.messages.empty?
> True
@conversation.messages.exists?
> False
Which are all expected values. But adding any of these methods in my Rails code throws an error:
NoMethodError (undefined method `messages' for #<Conversation::ActiveRecord_AssociationRelation:0x007fa187ca1ec8>)`
Which I guess is showing up because messages don't exist for that conversation so it can't find any association for that conversation. I'm not sure why this method would be inconsistent though.
EDIT: Adding the error causing code.
conversation_with_player_client = @client.conversations.select{|c| c.player_client_id == @game.player_client.id}
if conversation_with_player_client.count == 0
@conversation = @client.conversations.build({player_client_id: @game.player_client.id})
@conversation.save!
else
@conversation = @client.conversations.where({ player_client_id: @game.player_client.id })
end
puts "the conversation we found was #{@conversation.inspect}"
# This gives the response
# #<Conversation id: 7, player_client_id: 1, client_id: 11, created_at: "2018-02-12 20:55:55", updated_at: "2018-02-12 20:55:55">
# in the console so it can get the conversation
if @conversation.messages.any?
# this line is causing the error
Upvotes: 0
Views: 77
Reputation: 1833
The another way with find_or_create_by
method:
@client.conversations.find_or_create_by(player_client: @game.player_client.id)
To find more info:
https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by
Upvotes: 0
Reputation: 546
That error is due to you calling messages
on a collection of conversations rather than a single conversation.
I'd be willing to bet the offending code is something like:
client.conversations.messages #=> NoMethodError
Instead, it should be:
client.conversations.first.messages
EDIT - this is the line causing the error:
@conversation = @client.conversations.where({ player_client: @game.player_client.id })
where
will return a relation representing many conversations. If you only want a single conversation, you can use find_by
:
@conversation = @client.conversations.find_by({ player_client: @game.player_client.id })
Upvotes: 2
Reputation: 3005
In your code:
@conversation = @client.conversations.where({ player_client: @game.player_client.id })
is not a conversation. Is more than one. You cannot use messages there.
If you need only one conversation, you must change where by find_by.
If not, you need to iterate through all conversations.
Upvotes: 0
Reputation: 3398
Did you tried with present?
method? Guess it would work better... like this:
@conversation.messages.present?
It will return false if messages is nil or empty, so I guess it fits better. Good luck!
Upvotes: 0