6

Rails 3.2アプリで問題が発生し、JSONを介して安らかに送信された仮想属性がparamsハッシュの適切な場所にありません。まあ、それは私が期待する場所ではありません。私の期待が正しいかどうかはまだ分からない。:)

次のような標準の仮想属性パターンを使用するモデルがあります。

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

コントローラに送信されるJSONは次のようになります。

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

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

railsが魔法をかけた後、私はこれをparamsハッシュに入れてしまいます。

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

ご覧のとおり、idとnameはネストされた:trackハッシュになりますが、評価はそうではありません。これは予想される動作ですか?ネストされたハッシュには必要なすべてのパラメーターが含まれていないため、コントローラーでネストされたハッシュを使用するという(ある程度)標準的な方法に違反します。

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

ご協力いただきありがとうございます!

4

3 に答える 3

7

私も最近、この落とし穴に遭遇しました。問題は、params ラッパーがモデルの Track.attribute_names を調べて、データを :track => {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 を呼び出して、パラメーターをラップするときに含める属性をアクション コントローラーに指示できます。

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

詳細はこちら: http://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

于 2012-10-03T20:23:38.867 に答える
0

おそらく、次のratingようにネストされたハッシュ内に仮想属性を割り当てると:

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

期待どおりに動作します。

于 2012-07-25T12:37:39.510 に答える
0

この問題に遭遇し、かなりまともな解決策を見つけました。以下を ApplicationController に追加します

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

このようにして、すべてがリソースの下にネストされ (Rails が params ハッシュに追加するものを除く)、wrap_parameters のコントローラー固有の呼び出しに再度追加する必要がなくなります。:D

于 2016-05-09T21:24:23.617 に答える