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

时间:2013-05-11 03:32:02

标签: 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

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

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

class Character < ActiveRecord::Base
  belongs_to :player

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

我不喜欢这个有几个原因。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:19)

如果您主要处理与视图相关的代码,您可能会发现在allow_nil: true电话上使用“或”与delegate一起使用感觉很自然:

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

您可以考虑的另一个有趣模式是null object pattern;使用此模式,您可以使用表示该对象的“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

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

最后,the code for delegate isn't too complicated。您可以编写自己的此方法版本,在default的情况下使用nil参数:

delegate :name, to: :player, prefix: :player, default: 'Unknown'