Method each strange behavior with AR association

Hi. I write

<%= Chat.find_by(id: 6).chatusers.each { |chat_user| chat_user.user.inspect } %>

(There are three models: Chat, Chatuser, User)

Chat.find_by(id: 6).chatusers returns collection of table “chats_users” and this is fine working.

But i can not get model user by each element of collection in method “each”.

So, question is why each not working to get relative model “user” or how to resolve my task by each or another way.

Thanks.

What error are you getting (copy/paste it from the log please)? Also copy/paste the section of chat_user.rb showing the associations.

Colin

There are no errors given. Instead rails puts result of Chat.find_by(id: 6).chatusers, not result of “each”, that’s strange.

class Chatuser < ActiveRecord::Base

self.table_name = “chats_users”

belongs_to :chat

belongs_to :user

validates :chat_id, presence: true

validates :user_id, presence: true

end

There are no errors given. Instead rails puts result of Chat.find_by(id: 6).chatusers, not result of "each", that's strange.

Now I look again that is not surprising. The method inspect outputs to the server terminal window not to the html for display, if you look in the server window you should see it. You need to do something like

<% Chat.find_by(id: 6).chatusers.each do |chat_user| %> <%= chat_user.user.name %> <% end %>

If you are trying to get debug out then the best way is <% logger.info Chat.find_by(id: 6).chatusers.each { |chat_user| chat_user.user.inspect %> which will appear in development.log. You can also use logger.info in model or controller.

Colin

Great ! I already try write this logic but it not works. But when i copy-paste your variant it’s work.

So difference is in formating code, i write in one line, you write in three lines.

That’s nice for resolving problem, but why it’s works in divided style of ruby and not works in one-line style ?

My one-line is <%= Chat.find_by(id: 6).chatusers.each { |chat_user| chat_user.user } %> which about i told.

Great ! I already try write this logic but it not works. But when i copy-paste your variant it’s work.

So difference is in formating code, i write in one line, you write in three lines.

That’s nice for resolving problem, but why it’s works in divided style of ruby and not works in one-line style ?

My one-line is <%= Chat.find_by(id: 6).chatusers.each { |chat_user| chat_user.user } %> which about i told.

So you have:

<%= something %>

which ERB interprets as call .to_s on the result of evaluating something and add that to the output (possibly after making it HTML-safe depending on your Ruby on Rail version)

Therefore, what is the value of

Chat.find_by(id: 6).chatusers.each { |chat_user| chat_user.user }

Well, that’s just something.each {|…| … } which has the value of something. In your case, the same as if you just had:

Chat.find_by(id: 6).chatusers

This is probably some ActiveRecord proxy for the association. The default .to_s is very likely similar to .inspect and looks something like:

#<ActiveRecord::… >

So plop that into your HTML and a browser sees the <…> as an unknown element and does nothing so you’re left with:

in your page. Does that make sense to you?

-Rob

The problem is that ruby is swallowing whatever happens inside the .each -- what you want is probably .map instead. The return value from .each is the collection. The return value from map is a new collection of the results of the block.

Try this:

    Chat.find_by(id: 6).chatusers.map{|chat_user| chat_user.user}