6

私のアプリケーションのほとんどには、current_userメソッドがあります。current_user.namewhere current_userisのような場合の例外を避けるためにnil、rails はtryメソッドを提供します。tryこれに関する問題は、どこにでも使用することを覚えておく必要がcurrent_userあることnilです。

Null Object パターンを使用して、この追加のオーバーヘッドを取り除きたいと考えています。

class NullUser
  def method_missing(method_name, *args)
    nil
  end
end

def current_user
  return NullUser.new unless UserSession.find
  @current_user ||= UserSession.find.user
end

tryこれは、場合によっては置き換えることができます。

current_user.try(:first_name)     #=> nil
current_user.first_name           #=> nil

しかし、さらに連鎖すると失敗します:

current_user.profiles.first.name    #=> undefined method...

null オブジェクトを返そうとしました:

class NullUser
  def method_missing(method_name, *args)
    self.class.new
  end
end

current_user.try { |u| u.profiles.first.name }  #=> nil
current_user.profiles.first.name                #=> nil

しかし、これは他の場合には失敗します:

current_user.is_admin?            #=>  #<NullUser:0x96f4e98>

この問題の解決策はありますか、それとも私たち全員が共に生きなければなりませtryんか?

4

2 に答える 2

8

をそのまま使用しますが、わかりやすくするためNullUserに名前を に変更しGuestUserます。さらに、 User クラスからすべての重要なメソッドをスタブする必要があります。

class GuestUser
  def method_missing(method_name, *args)
    nil
  end

  def is_admin?
    false
  end

  # maybe even fields:
  def name
    "Guest"
  end

  # ...
end
于 2013-04-18T11:24:36.887 に答える
3

NullUserインスタンスでメソッドをチェーンできるようにしたい場合は、代わりにmethod_missingreturnが必要です。あなたは戻ってしようとしました...selfnilself.class.new

Avdi Grim が、Ruby で Null オブジェクト パターンを実装する方法を説明しています。

于 2014-04-23T22:00:11.350 に答える