Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delegated with nil property in ruby

For some reason that I am not understanding I get this error message when running a certain page on my app:

Teamplayer#Plyr delegated to live_player.Plyr, but live_player is nil: #<Teamplayer id: 1, playerid: "2533033", teamid: "1", live_player_id: 253303, fteam_id: "1", created_at: "2014-05-12 13:57:49", updated_at: "2014-05-12 13:57:49">

On this line:

<%= @teamplayer.Plyr %>

Here is how my model for Teamplayer is set up:

class Teamplayer < ActiveRecord::Base
belongs_to :live_player
belongs_to :fteam
    delegate :Plyr, to: :live_player
delegate :Team, to: :live_player
delegate :Nid, to: :live_player
delegate :name_team, to: :live_player
delegate :fanteam, to: :fteam

end

Here is the Liveplayer model:

class LivePlayer < ActiveRecord::Base
has_many :fteams, through:  :teamplayers
end

Here is the Fteam model since it is mentioned above:

class Fteam < ActiveRecord::Base
has_many :teamplayers
has_many :live_players, through: :teamplayers
end

I am trying to get the field Plyr from live_player (which comes from the table called live_players), but it is saying that the live_player is empty. I am not sure which part of this is wrong. I am using postgresql, but I don't think that has an effect on it.

If anyone needs more information to help me with this, I will be more then happy to post it

like image 782
user3240928 Avatar asked May 12 '14 18:05

user3240928


People also ask

What does delegate do in Ruby?

The delegate method allows you to optionally pass allow_nil and a prefix as well. Ultimately this allows us to query for data in custom ways.

What is Simpledelegator?

A concrete implementation of Delegator , this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with #__setobj__.


1 Answers

delegate has an allow_nil option that will return nil on a delegated method if the delegate object is not present:

delegate :Plyr, to: :live_player, allow_nil: true

This will basically let live_player.Plyr fail silently instead of raising the error.

As an aside, methods in Ruby are lowercase 99.99999% of the time (there are a few capitalized Kernel methods), and there's no limit on the number of characters (I would use player rather than Plyr for readability). If that's a column name on an inherited database, I would try to correct it. By convention, Rails uses lowercase database table and column names, and this might cause some strange issues later on.

EDIT

Without actually knowing how you need to use this, generally I would suggest using the Null Object pattern to show the missing player condition (I find it easier to reason about an object that represents nothingness rather than checking for nil every other line). Create a new class called NullPlayer that responds to the same methods that a player would, but in a way to makes it clear there is no player present:

class NullPlayer
  def name
    "[no player]"
  end

  # etc ...
end

Unfortunately, I don't know of a way to default to the null object using Rails' standard delegation, so to use it, you'll need to do something like this:

teamplayer.Plyr || NullPlayer.new
like image 150
Zach Kemp Avatar answered Oct 04 '22 13:10

Zach Kemp