1

So I have done this kind of thing countless times in the past, but I can't seem to wrap my head around why this isn't working this time. I am fairly new to RoR and I was using some new relations in my model, that is the only reason I can think of so far.

User model has the following relations

  has_one :profile

  has_many :follower_relationships, class_name: "Follow", foreign_key: "following_id"
  has_many :followers, through: :follower_relationships, source: :follower

  has_many :following_relationships, class_name: "Follow", foreign_key: "user_id"
  has_many :following, through: :following_relationships, source: :following

I am trying to list the followers of any one particular user, but the names are stored in the user profile. I have tried doing this:

In the conroller: 

def followers
  @followers = User.find_by(id: params[:user_id]).followers
end

In the html.erb file:

<% for i in [email protected] %>
   <%= @followers[i].profile.first_name %>
<% end %>

So, I initially tried for.each before trying a ordinary for loop. But it always returns

ActionView::Template::Error (undefined method `first_name' for nil:NilClass):
    2:
    3:
    4: <% for i in [email protected] %>
    5: <%= @followers[i].profile.first_name %>
    6: <% end %>

However, putting <%= @followers.first.profile.first_name %> returns the first_name of the first follower.

Why does calling the first item in the array work when I am trying this but not when I am trying to iterate over the entire array?

8
  • 1
    Very rarely would a for loop be used in ruby instead this would be <% @followers.each do |follower| %> then you would just use the piped local variable follower inside the block. Also just because @followers.first has a profile does not mean that @followers.forty_two does Commented May 27, 2020 at 20:37
  • I seeded the database... so all of them have profiles. Also, I did use <% @followers.each do |follower| %> as I said in the question but it returned the same thing. Commented May 27, 2020 at 20:43
  • Then one of the followers does not have a profile. Try this and see User.find_by(id: params[:user_id]).followers.left_joins(:profile).where(profiles: {id: nil}) Commented May 27, 2020 at 20:47
  • It didn't return anything #<ActiveRecord::AssociationRelation []>. I seeded every profile and user in the database together, so all users present have profiles. Commented May 27, 2020 at 21:02
  • There is no reason for that error in that location except that profile returns nil. Try changing to profile&.first_name and see where the empty result is. Commented May 27, 2020 at 21:09

1 Answer 1

2

Well... if you use a for-loop. You should probably go from 0..(@followers.length - 1) if not, it'll return a (undefined methodfirst_name' for nil:NilClass)` error like you are seeing.

<% for i in 0..(@followers.length-1) %>
   <%= @followers[i].profile.first_name %>
<% end %>

or better yet, use the for.each and send the error. if there is any.

<% @followers.each do |f| %>
  <%= f.profile.first_name %>
<% end %>
Sign up to request clarification or add additional context in comments.

2 Comments

I must have made a typo or something when I was using the .each, cause it is working now. @engineersmnky
@ChandlerWhite the .where query method always returns a relation (an array). the .each loops through each index of it.

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.