2016-03-22 9 views
0

あなたのうちの何人かはすでにこれで私の正気を疑っていることは分かっています。私はActiveRecordクラスを持っています。このクラスは、欠けているメソッドを使用して、JSON属性内に掘り下げています。Rails/Rspec respond_to method_missing lookup

# app/models/request_interactor.rb 

    ... 

    def method_missing(method_sym, *arguments, &block) 
    return self.request_params[method_sym.to_s] if self.request_params[method_sym.to_s] 
    super 
    end 

テストは、私は、テスト内で結合しようとしたこの

before(:each) do 
    @ri = RequestInteractor.create(result: {magic_school: true, magic_learnt: 'all things magical'}, request_params: {application_id: 34, school_id: 20, school_name: 'Hogwarts', course_name: 'Defence against the Dark Arts.'}) 
end 

it 'should respond to attributes set in the request parameters' do 
    expect(@ri).to respond_to(:school_name) 
    expect(@ri.school_name).to eq('Hogwarts') 
end 

@ri.school_name'Hogwarts'をeqでますように見えますが、それはresponds_toを実行するとき、それはそのような方法は存在しないと言って失敗します!汚い、汚れた嘘つき!

私がモデルにこのような何かをやってみました:私の一日の運命はあなたの中にある今..だから

def respond_to?(method, include_private = false) 
    super || self.respond_to?(method, include_private) 
end 

しかし、これが原因で再帰の、ために再帰の、あまりにも深いスタックレベルを返します。手!大いなるものを私に教えてください。どのようにしてメソッドの欠落に対する応答をテストしますか?

答えて

2

respond_to_missingを使用してください。その他の情報here

今、このすべてが言われています。あなたが私に尋ねると、あなたのパターンはまだハッキーに見えます。

リファクタリング

Rubyはこれをきれいにする方法のトンを持っています。

  1. 委任パターン

    delegate :method_name, :to => :request_params

    を(docに他のオプションを確認してください)を使用します。これはオブジェクトにメソッドを持たせることで問題を解決するはずですので、respond_to?が機能し、method_missingを上書きしないようにします。

  2. request_params(アクセサのメタプログラミング)を設定するときは、アクセス方法を生成してください。

  3. request_paramsのようにHashで初期化できるため、を使用してください。あなたが上に委任を加えるなら、あなたはすばらしくすべきです。

希望します。

+0

Hey @muichkineご意見ありがとうございます、私は委任パターンの使用については考えていませんでした。私は本当に好きです!私が使用している唯一の予約は、 'request_params'がJSONオブジェクトであるため、ハッシュであるかのようにこれにアクセスする必要があるということです。だから、おそらくメソッドを忘れたままにしてから、デリゲートパターンを使って応答するためのフックを提供してください。要求パラメータはオブジェクトに早期に割り当てられ、RIオブジェクトは後で保存されるので、アクセサのメタにはbefore_saveフィルタを使用する必要があります。それは最高のように見える代表団のパターンを試してみましょう:) TY – TheLegend