Method each strange behavior with AR association


#1

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.


#2

On 4 September 2015 at 14:46, Николай Спелый removed_email_address@domain.invalid
wrote:

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

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


#3

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


#4

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.


#5

On 2015-Sep-4, at 15:56 , Николай Спелый removed_email_address@domain.invalid wrote:

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


#6

On 4 September 2015 at 15:32, Николай Спелый removed_email_address@domain.invalid
wrote:

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


#7

On Fri, Sep 4, 2015 at 3:26 PM, Rob B.
removed_email_address@domain.invalid
wrote:

chat_user.user } %> which about i told.

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}