2017-04-17 10 views
1

Rails 5にアップグレードした後、jQueryの.ajaxリクエストに問題があります。私はこれが(幾分)新しい強力なパラメータと関係していると信じています。次のエラーが表示されます。Rails 5 jQuery .ajaxメソッドのデータ形式

ArgumentError (When assigning attributes, you must pass a hash as an argument.): 

私の.ajaxリクエスト(Coffeescriptを使用)でデータパッケージを正しく設定していないと考えています。

おそらく、私の信頼できるパラメータが正しく動作していない可能性があります。

byebugを使用すると、私のコントローラの最初の行は大丈夫ですが、2行目で失敗します。@prospect.update(prospect_params[:status])

1: @_params = <ActionController::Parameters {"prospect"=><ActionController::Parameters {"id"=>"16", "status"=>"inactive"} permitted: false>, "controller"=>"prospects", "action"=>"update_status"} permitted: false> 
ここ

私のコントローラからの抜粋であり、Coffescript

コントローラ

# PUT /prospects/update_status 
    def update_status 
    @prospect = Prospect.find(params[:id]) 
    @prospect.update(prospect_params[:status]) 

    respond_to do |format| 
     if @prospect.update_attributes(prospect_params) 
     format.json { head :no_content } 
     else 
     format.json { render json: @prospect.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

...

private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_prospect 
    @prospect = Prospect.find(params[:id]) 
    end 

    # Only allow a trusted parameter "white list" through. 
    def prospect_params 
    params.require(:prospect).permit(:name, :status, :priority, :id) 
    end 

:ここbyebugで@_params変数ですCoffeescript

# Update prospects active list when a toggle switch is clicked 
    $("#prospects_list").on "change", ".js-switch", -> 
     prospect_id = $(this).parent('form').find('input[name="prospect[id]"]').val() 
     if @checked 
      status = 'active' 
     else 
      prospect_status = 'inactive' 
     # Get parent TR 
     tr = $(this).closest('tr') 
     # Update prospect using Ajax 
     $.ajax 
      url: '/prospects/update_status' 
      type: 'POST' 
      data: { prospect: {id: prospect_id, status: prospect_status } } 
      dataType: 'json' 
      success: (data) -> 
       return 
      false 
+0

に小さな変更が必要? – the12

答えて

0

私は正しい方向に私を得るためにЗелёныйとmaxに感謝します。ここでは私が使用したものが働いています。私は、コントローラ

コントローラあなたが見えるようにparamsハッシュをしたいですかどう

# PUT /prospects/update_status 
def update_status 
    @prospect = Prospect.find(prospect_params[:id]) 
    respond_to do |format| 
    if @prospect.update(status: prospect_params[:status]) 
     format.json { head :no_content } 
    else 
     format.json { render json: @prospect.errors, status: :unprocessable_entity } 
    end 
    end 
end 
3

パラメータの値を渡します。あなたが本当に更新するための特定のルートが必要な場合は、自分自身に尋ねることによって

@prospect.update(status: prospect_params[:status]) 
+0

ありがとうございました。これはちょっと混乱していましたが、私はハッシュが何であるか分かりませんでしたが、それは正しい構文になるのを助けました。私は別の答えでそれを掲示するでしょう。 – Ryan

0

スタート:

@prospect.update(prospect_params) 
# that's pass a hash 
# prospect_params => {"id"=>"16", "status"=>"inactive"} 

または:you must pass a hash as an argument.

@prospect.update(prospect_params[:status]) 
# here is you pass a value of status key, that's not a hash 
# {"id"=>"16", "status"=>"inactive"} 
# prospect_params[:status] => "inactive" 

使用だけで、エラーメッセージで

ルックステータスまたはこれが正規の更新ルートへのリクエストである場合:

あなたはAJAXハンドラを変更する必要があり、その場合には
PATCH /prospects/:id 

# Update prospects active list when a toggle switch is clicked 
$("#prospects_list").on "change", ".js-switch", -> 
    prospect_id = $(this).parent('form').find('input[name="prospect[id]"]').val() 
    if @checked 
     status = 'active' 
    else 
     prospect_status = 'inactive' 
    # Get parent TR 
    tr = $(this).closest('tr') 
    # Update prospect using Ajax 
    $.ajax 
     url: '/prospects/' + prospect_id 
     type: 'PATCH' # Not POST! 
     data: { prospect: { status: prospect_status } } 
     dataType: 'json' 
     success: (data) -> 
      return 
     false 

何らかの理由であなたは、このための具体的な方法をしたい場合は、あなたが移動することによって、それを修正することができます。idパスへの代わりに、 params。 @prospect.update(prospect_params[:status])を使用して

# config/routes.rb 
resources :prospects do 
    member do 
    patch :update_status 
    end 
end 

# PATCH /prospects/:id/update_status 
def update_status 
    @prospect = Prospect.find(params[:id]) 
    respond_to do |format| 
    if @prospect.update_attributes(prospect_params) 
     format.json { head :no_content } 
    else 
     format.json { render json: @prospect.errors, status: :unprocessable_entity } 
    end 
    end 
end 

# ... 

def prospect_params 
    params.require(:prospect).permit(:name, :status, :priority) 
end 

# coffeescript 
url: '/prospects/' + prospect_id +'/update_status' 

二回の記録を更新しても、それは例外が発生しますので、強いパラメータをスカートました。

+0

Railsのバージョンは、セマンティクスがレコードの更新をより良く一致させるため、PUTで​​はなくPATCHを使用します。 – max

+0

ダブルアップデートをキャッチしてくれてありがとう。私はそれを修正した。次はPATCHを試してみるつもりですが、今はjqueryの多くの呼び出しでこれを再現しなければならないため、できるだけ少数の変更が必要でした。 – Ryan

+0

これを複製している場合は間違っています。更新(オブジェクト)を取り、[約束オブジェクト]を返す単純なjavascript関数を定義します(http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/)( 'return $ .ajax(...)')です。次に、promiseオブジェクトで '.done'を使ってコールバックを定義します。 – max

関連する問題