Home Inconsistent rails method `exists` and `any?`
Reply: 4

Inconsistent rails method `exists` and `any?`

anonn023432
1#
anonn023432 Published in 2018-02-12 21:57:45Z

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
Mitch
2#
Mitch Reply to 2018-02-12 22:11:19Z

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 })

Ronan Lopes
3#
Ronan Lopes Reply to 2018-02-12 22:02:47Z

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!

Pablo
4#
Pablo Reply to 2018-02-12 22:10:49Z

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.

hamdi
5#
hamdi Reply to 2018-02-12 22:18:07Z

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

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.300133 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO