Rails 3:具有nil关系的方法委派

Cat*_*arz 6 ruby activerecord ruby-on-rails-3.1

鉴于以下(大大简化)对象:

class Player < ActiveRecord::Base
  has_many :characters
end

class Character < ActiveRecord::Base
  belongs_to :player
  delegate :name, :to => :player, :prefix => :player
end
Run Code Online (Sandbox Code Playgroud)

我需要在几个视图中显示播放器名称.但完全有效(并且预期)玩家可能是零.

我目前通过以下方法处理此问题:

class Character < ActiveRecord::Base
  belongs_to :player

  def player_name
    player ? player.name : 'Unknown'
  end
end
Run Code Online (Sandbox Code Playgroud)

出于几个原因我不喜欢这个.这样做有更好的方法吗?

Mic*_*ley 20

如果您主要处理与视图相关的代码,您可能会发现allow_nil: truedelegate通话中使用"或" 感觉很自然:

Name: <%= @character.player_name || 'Unknown' %>
Run Code Online (Sandbox Code Playgroud)

您可以考虑的另一个有趣的模式是空对象模式 ; 使用此模式,您可以使用表示该对象的"null"或缺失值的对象来描述"默认"行为.例如,(伪代码):

class NullPlayer
  def name
    'Unknown'
  end
end

class Character < ActiveRecord::Base
  belongs_to :player

  delegate :name, to: :player, prefix: :player, allow_nil: true

  # overwrite default player accessor
  def player
    super || NullPlayer.new
  end
end
Run Code Online (Sandbox Code Playgroud)

这种模式有点重,但您可能会发现它取决于您的应用程序.

最后,代码delegate并不太复杂.您可以编写自己的此方法版本,该方法default在以下情况下使用参数nil:

delegate :name, to: :player, prefix: :player, default: 'Unknown'
Run Code Online (Sandbox Code Playgroud)