2012-02-19 7 views
6

Rails 3.2アプリケーションで、JSON経由で虚偽の送信された仮想属性がparamsハッシュの適切な場所にない問題が発生しています。まあ、それは私が期待している場所ではありません。私の期待が正しいかどうかはまだ分かりません。 :) params内のモデルハッシュに仮想属性が移動されない

が、私はこのような標準的な仮想属性のパターンを使用してモデル、持っている:JSONは私のコントローラに送信

class Track < ActiveRecord::Base 
    def rating 
    # get logic removed for brevity 
    end 

    def rating=(value) 
    # set logic 
    end 

    def as_json(options={}) # so my method is in the JSON when I use respond_with/to_json 
    super(options.merge(methods: [:rating])) 
    end 
end 

は次のようになります。

{"id":1,"name":"Icarus - Main Theme 2","rating":2} 

を明確にするために、名前とidは仮想ではなく、評価はisです。

レールはその魔法ん後、私は、paramsハッシュにこれで終わる:あなたが見ることができるように、IDと名前は、ネストされたにそれを

{"id"=>"1", "name"=>"Icarus - Main Theme 2", "rating"=>2, "track"=>{"id"=>"1", "name"=>"Icarus - Main Theme 2"}} 

します:トラックのハッシュを、しかし、評価はしていません。これは予想される動作ですか?ネストされたハッシュに必要なすべてのパラメータが含まれていないため、コントローラでネストされたハッシュを使用するという(いくらか)標準的な慣行が破られます。

Track.update(params[:id], params[:track]) # :track is missing rating 

ありがとうございました!あなたはこのようなネストされたハッシュ内部rating仮想属性割り当てた場合

+0

提出を行っているフォームを貼り付けることができますが、それはトラックに正しくスコープがないように見えます – MatthewFord

答えて

7

私は最近、このような問題に直面しました。問題は、paramsラッパーがあなたのモデルTrack.attribute_namesを見て、データを:track => {params}ハッシュにどのようにマップするかを決定することです。あなたはモデルが関連付けられていない場合は、デフォルトでは、コントローラ名に基づいてのparamsをラップすること、および値のすべてが含まれます:

class SinglesController < ApplicationController 
    def create 
    #params[:single] will contain all of your attributes as it doesn't 
    # have an activerecord model to look at. 
    @track_single = Track.new(params[:single]) 
    end 
end 

あなたはどのようなアクションコントローラを伝えるために、あなたのコントローラでwrap_parametersを呼び出すことができますそのがそうのように、あなたのparamsをラップするとき含める属性:

class TracksController < ApplicationController 
    wrap_parameters :track, :include => :rating 
    #other controller stuff below 
end 

は、ここで詳細を参照してください。http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

+3

私は同様の問題を抱えています、wrap_parametersを使用すると、それらのすべてがインクルード配列に渡されます。それ以外の場合は、リクエストハッシュには含まれません。簡単な方法でこれを行う方法は?リクエストハッシュに含める仮想属性が1つだけあるからです。ありがとう – user1883793

0

多分:

def as_json(options={}) 
    super(options.merge(:track => {:methods => @rating})) 
end 

をそれはあなたが期待されるように動作するでしょう。

0

はちょうどこの問題に出くわしましたし、かなりまともな解決策を考え出しました。この方法

wrap_parameters exclude: [:controller, :action, :format] + ActionController::ParamsWrapper::EXCLUDE_PARAMETERS 

あなたのApplicationControllerにに以下を追加し、すべてがあなたのリソースの下にネストされた(スタッフのRails以外のparamsハッシュに追加されます)、あなたは二度とwrap_parametersのコントローラ特定のコールに追加する必要はありません。 :

関連する問題