7

给定以下(大大简化的)对象:

class Player < ActiveRecord::Base
  has_many :characters
end

class Character < ActiveRecord::Base
  belongs_to :player
  delegate :name, :to => :player, :prefix => :player
end

我需要在多个视图中显示玩家名称。但是 Player 可能为零是完全有效的(并且可以预期)。

我目前通过以下方法处理了这个问题:

class Character < ActiveRecord::Base
  belongs_to :player

  def player_name
    player ? player.name : 'Unknown'
  end
end

我不喜欢这个有几个原因。有没有更好的方法来做到这一点?

4

1 回答 1

23

如果您正在处理大部分与视图相关的代码,您可能会发现allow_nil: truedelegate调用中使用“或”结合起来感觉很自然:

Name: <%= @character.player_name || 'Unknown' %>

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

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

这种模式有点笨拙,但您可能会发现它适合您的应用程序。

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

delegate :name, to: :player, prefix: :player, default: 'Unknown'
于 2013-05-11T05:41:47.840 回答