1

だから私は基本的なメンバー変更アクションを書いています、そして私は考えました、DRYのままにして、paramsハッシュを変更してから私たちのupdateメソッドに渡すだけですが、それはうまくいかないようです。私が見つけることができないいくつかのレールの魔法が起こっていると思います...私が読んだものから、これはうまくいくはずです。Rails3.2を使用しています。

これが私がやろうとしていることの例です:

  # POST /tasks/1/toggle_done
  def toggle_done
    @task = Task.find(params[:id])
    puts "<<<<<", params

    # invert done bool value
    params[:done] = !(@task.done)

    # thought maybe update_attributes retured a full set of 
    # attributes in the params...
    #params[:name] = @task.name + "...test."

    # thought maybe the method call to update was getting 
    # filtered or something. Doesn't seem to help.
    #params[:_method] = "put"
    # redirect to update with these new params

    puts ">>>>>", params

    # Why bother rewriting task.done = x; task.save; 
    # redirect_to show; etc when update already does that.
    update
  end

  # PUT /tasks/1
  # PUT /tasks/1.json
  def update
    @task = Task.find(params[:id])

    puts "======", params

    respond_to do |format|
      if @task.update_attributes(params[:task])
        format.html { redirect_to @task, notice: 'Task was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

次のコンソール出力が表示されます。

<<<<<
{"_method"=>"post", "authenticity_token"=>"CVqzsJfSVgM7Bq/kXlrjzkWVoA7Pbne4GNEHqbQB42s=", "action"=>"toggle_done", "controller"=>"tasks", "id"=>"1"}
>>>>>
{"_method"=>"put", "authenticity_token"=>"CVqzsJfSVgM7Bq/kXlrjzkWVoA7Pbne4GNEHqbQB42s=", "action"=>"toggle_done", "controller"=>"tasks", "id"=>"1", "done"=>false, "name"=>"Put Done button in index view...test."}
======
{"_method"=>"put", "authenticity_token"=>"CVqzsJfSVgM7Bq/kXlrjzkWVoA7Pbne4GNEHqbQB42s=", "action"=>"toggle_done", "controller"=>"tasks", "id"=>"1", "done"=>false, "name"=>"Put Done button in index view...test."}

したがって、params配列が正しく設定されているようです。「タスクは正常に更新されました。」というフラッシュメッセージが表示された通常のshowビューがレンダリングされるため、メソッド全体が実行されたように見えますが、モデルのプロパティは変更されていません。update_attributes内の何かが失敗していると思います。誰かが私のためにこれにいくつかの光を当てることができますか?

また、これはクレイジーなことですか?更新するためにチェーンするのではなく、toggle_doneメソッド内で設定して保存する必要がありますか?

4

2 に答える 2

3

Rails はタスク オブジェクトの属性を hash に保存しますparams[:task]。したがって、toggle_doneメソッドで結果を保存する必要があります。そうしないと、レールは属性をタスクにparams[:task][:done]関連付けることができません。done

def toggle_done
  @task = Task.find(params[:id])
  params[:task] = { done: !(@task.done) }
  update
end

しかし、更新メソッドを呼び出すと、2 つだけが必要な 3 つのデータベース クエリを作成します。最初の 2 つは同じです。toggle_doneメソッドと同様に ID を使用してタスクをロードするためですupdate

これを回避するには、保存およびリダイレクト部分を保護されたメソッドに配置し、保存するときに呼び出すことができます。このような:

def toggle_done
  @task = Task.find(params[:id])
  params[:task] =  { done: !(@task.done) }
  save_updated
end

def update
  @task = Task.find(params[:id])
  save_updated
end

protected
def save_updated
    respond_to do |format|
      if @task.update_attributes(params[:task])
        format.html { redirect_to @task, notice: 'Task was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
end
于 2012-04-22T14:42:17.980 に答える
2

params[:task] を update_attributes に渡していますが、これは存在しません。試す:

params[:task] = {:done => !(@task.done)}
于 2012-04-22T14:37:43.003 に答える