web-dev-qa-db-ja.com

Rails 5:パラメーターからハッシュ値を取得できません

奇妙な問題に直面しています。

undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>

変数をパラメーターハッシュに割り当て、その値を取得しようとすると、エラーが発生します。

attributes = params[:line_item][:line_item_attributes_attributes] || {}
attributes.values

パラメーターは、ハッシュのハッシュのように見えます。

{"0"=>{"product_attribute_id"=>"4"}, "1"=>{"product_attribute_id"=>"7"}}

今、コンソールでこれを行い、それを変数属性に割り当てると、問題なく動作します。だから私はここで何が機能していないのか、そしてそれを機能させる方法を理解するのに苦労しています。

this をご覧ください。 ActionController::ParametersはHashのサブクラスであるため、非常に奇妙です。paramsハッシュのto_hメソッドを使用して、 直接 をハッシュに変換できます。

ただし、to_hはホワイトリストに登録されたパラメーターでのみ機能するため、次のようなことができます。

permitted = params.require(:line_item).permit(: line_item_attributes_attributes)
attributes = permitted.to_h || {}
attributes.values

ただし、代わりにホワイトリストに登録したくない場合は、to_unsafe_hメソッドを使用するだけです。

更新

私はこの問題に非常に興味があったので、調査を開始しましたが、あなたはRails 5を使用していることを明確にしたので、これがこの問題の原因です。 Rails 4.xのように、ActionController::ParametersはHashのサブクラスであるため、実際にvaluesメソッドに応答する必要がありますただし、Rails 5 ActionController::Parametersは、ハッシュではなくオブジェクトを返すようになりました

:これは、params[:id]などのparamsハッシュのキーへのアクセスには影響しません。この変更を実装した Pull Request を表示できます。

オブジェクトのパラメーターにアクセスするには、to_hをパラメーターに追加できます。

params.to_h

to_hActionController::Parametersメソッドを見ると、パラメーターをハッシュに変換する前にパラメーターが許可されているかどうかを確認できます。

# actionpack/lib/action_controller/metal/strong_parameters.rb
def to_h
  if permitted?
    @parameters.to_h
  else
    slice(*self.class.always_permitted_parameters).permit!.to_h
  end
end

例えば例

def do_something_with_params
  params.slice(:param_1, :param_2)
end

どちらが返されます:

{ :param_1 => "a", :param_2 => "2" }

しかし、今ではActionController::Parametersオブジェクトを返します。

Param_1とparam_2は許可されていないため、これでto_hを呼び出すと空のハッシュが返されます。

ActionController::Parametersからparamsにアクセスするには、最初にparamsを許可してからオブジェクトでto_hを呼び出す必要があります

def do_something_with_params
  params.permit([:param_1, :param_2]).to_h
end

上記は、許可したばかりのパラメーターを含むハッシュを返しますが、パラメーターを許可せずにそのステップをスキップしたい場合は、to_unsafe_hashメソッドを使用する別の方法があります。

def do_something_with_params
  params.to_unsafe_h.slice(:param_1, :param_2)
end

特定のパラメーターを常に許可する場合は、application.rbの構成からのパラメーターを常に許可する方法があります。構成オプションを設定できます。注:これは、記号キーではなく、文字列キーを持つハッシュを返します。

#controller and action are parameters that are always permitter by default, but you need to add it in this config.
config.always_permitted_parameters = %w( controller action param_1 param_2)

これで、次のようなパラメータにアクセスできます。

def do_something_with_params
  params.slice("param_1", "param_2").to_h
end

キーは文字列であり、シンボルではないことに注意してください。

これが問題の根本を理解するのに役立つことを願っています。

ソース: eileen.codes

51
SsouLlesS

In Rails 5 paramsはクラス 'ActionController :: Parameters'であるため

Params.to_hを実行すると、次のエラーが表示されます。

*** ActionController::UnfilteredParameters Exception: unable to convert 
unpermitted parameters to hash

次のようにして、パラメータをハッシュ形式として取得できます。

parameters = params.permit(params.keys).to_h

ただし、これを使用することに注意してください!コードに害を及ぼす可能性のある未知のパラメーターを含む可能性のあるすべてのパラメーターを許可しています。

8
Abhi

私は何が起こっているのだと思います:

コンソールでは、attributesと呼ばれる単純なハッシュを使用しています。ハッシュとして、コンソールのattributesパラメーターには 有効なインスタンスメソッドvaluesと呼ばれます。

Railsアプリでは、paramsハッシュは単純なハッシュではなくなりました。これはActionController::Parametersクラスのインスタンスです。そのクラスのインスタンスとして、valuesがありますが、 呼び出されたインスタンスメソッドto_hto_unsafe_hがあり、これが目標を達成します。パラメータでto_hを呼び出した後、valuesメソッドを呼び出すことができます。

1
BigRon

賢明な言葉: sorted gemからlink_to_sortedを使用している場合、Rails 5。

0
cd-rum