5

ここでレールの Null オブジェクトに関するいくつかの回答を見たにもかかわらず、それらを機能させることができないようです。

class User < ActiveRecord::Base
  has_one :profile
  accepts_nested_attributes_for :profile

  def profile
    self.profile || NullProfile #I have also tried
    @profile || NullProfile #but it didn't work either
  end
end

class NullProfile
  def display #this method exists on the real Profile class
    ""
  end
end

class UsersController < ApplicationController
  def create
    User.new(params)
  end
end

私の問題は、ユーザーの作成時に、プロファイルに適切なネストされた属性 (profile_attributes) を渡すと、新しいユーザーに NullProfile が作成されることです。

これは、作成時にカスタム プロファイル メソッドが呼び出され、NullProfile が返されることを意味していると推測しています。この NullObject を適切に実行して、オブジェクトの最初の作成時ではなく読み取り時にのみ発生するようにするにはどうすればよいですか。

4

4 に答える 4

3

私は正確に行っていましたが、存在しない場合はクリーンな新しいオブジェクトが必要でした(これを行っている場合はobject.display、エラーが発生しない可能性object.try(:display)があります)これも、これが私が見つけたものです:

1: エイリアス/alias_method_chain

def profile_with_no_nill
  profile_without_no_nill || NullProfile
end
alias_method_chain :profile, :no_nill

ただし、alias_method_chain は非推奨になっているため、エッジにとどまっている場合は、手動でパターンを作成する必要があります...ここでの回答は、より優れたよりエレガントなソリューションを提供するようです

2(答えからの簡略化/実用版):

class User < ActiveRecord::Base
  has_one :profile
  accepts_nested_attributes_for :profile

  module ProfileNullObject
    def profile
      super || NullProfile
    end
  end
  include ProfileNullObject
end

注:この問題を行う順序(リンクされた回答で説明されています)


あなたが試したことについて:

あなたがしたとき

def profile
  @profile || NullProfile
end

Association が遅延ロードされているため (:include検索で指示しない限り)、期待どおりに動作しないため、@profile は nil です。そのため、常に NullProfile を取得しています。

def profile
  self.profile || NullProfile
end

メソッドが自分自身を呼び出しているため失敗します。つまり、再帰メソッドのようなものです。SystemStackError: stack level too deep

于 2013-03-19T18:57:25.783 に答える
2

受け入れられた回答にプライベートモジュールを含めるよりも簡単なオプションを見つけました。

associationメソッド fromを使用して、リーダー メソッドをオーバーライドし、関連付けられたオブジェクトを取得できますActiveRecord

class User < ApplicationRecord
  has_one :profile

  def profile
    association(:profile).load_target || NullProfile
  end
end # class User
于 2016-11-21T10:39:48.183 に答える
1

alias_method_chain を使用する代わりに、これを使用します。

def profile
  self[:profile] || NullProfile.new
end
于 2014-04-28T16:36:54.670 に答える