Reputation: 293
I will post all of relevent files below, first let me explain the problem. I have 3 models, Players, Teams and Ownerships. Players and Team both own Ownership. Players have a :team through their relationship with Ownerships (has_one :team, through: :ownership).
If I display a Player using the show action, I can access all of the attributes of Team, including the logo that is a paperclip attachment.
If I display all of the Players using the index action, I cannot access any of the Team attributes. If I display the team like this, <%= player.team %> , it displays an object reference like this #Team:0x007fef0b68cb10. If I try and access attributes for Team, <%= player.team.name %>, I get:
NoMethodError in Players#index undefined method `name' for nil:NilClass
My question is this: How can I create an index method for Players so that I can display the attributes for Team in the index view?
I have tried changing my index method to the following:
def index
@players = Player.all.sort_by{ |x| [x.position, x.last_name] }
@Team = Player.team
end
but it fails with
undefined method `team' for #
The models:
class Player < ActiveRecord::Base
has_one :team, through: :ownership
has_one :ownership
validates :name, presence: true
validates :position, presence: true
def last_name
self.name.split(' ')[1]
end
end
class Ownership < ActiveRecord::Base
belongs_to :player
belongs_to :team
validates :round, :pick, :team_id, presence: true
end
class Team < ActiveRecord::Base
has_many :ownerships
has_many :players, through: :ownerships
validates :name, presence: true
validates :division, presence: true
has_attached_file :logo , :styles => { :small => '10>', :medium => '40>', :large => '60>' }
validates_attachment_content_type :logo, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
end
The Players Controller:
class PlayersController < ApplicationController
def index
@players = Player.all.sort_by{ |x| [x.position, x.last_name] }
end
def not_picked
@players = Player.all.select { |m| m.team == nil}.sort_by{ |x| [x.position, x.last_name] }
end
def show
@player = Player.find(params[:id])
end
private
def player_params
params.require(:player).permit(:name, :position)
end
end
The relevant part of the Players index.html.erb:
<% @players.each do |player| %>
<tr>
<td></td>
<td><%= link_to player.name, player %></td>
<td><%= player.position %></td>
<td><%= player.team.name %> </td> <!--This throws the error -->
The Players show.html.erb (works fine):
<%= render 'welcome/menu' %>
<%= @player.name %>
<%= @player.team.name %>
<%= @player.ownership.pick %>
<%= @player.ownership.round %>
Upvotes: 1
Views: 196
Reputation: 34338
Seems like, some of your players don't have an associated team, so player.team
is nil
for them. And, in that case it's failing to get the team name with the error message:
NoMethodError in Players#index undefined method `name' for nil:NilClass
Try to use try by changing:
<td><%= player.team.name %>
To:
<td><%= player.try(:team).try(:name) %>
And, Player.team
is wrong, you can't do that as you did not define any class method team
in Player class.
Upvotes: 1