2012-04-22 18 views
1

私はアクションを変更する基本的なメンバーを書いています。私はDRY状態にしてparamsハッシュを変更してからupdateメソッドに渡しますが、動作しないようです。私は見つけることができないいくつかのレール魔法があると思う...私はこれを読んだことからうまくいくはずです。私はRails 3.2を使用しています。ここでレール3の別のアクションから更新アクションを呼び出すにはどうすればよいですか?

は私がやろうとしているものの例です:

# 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メソッドの中で設定して保存するべきですか?

答えて

3

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

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

しかし、あなたは3つのデータベースのみ2がneccessaryあるクエリ作るupdateメソッドを呼び出すと

- あなたは toggle_done方法でIDと同様に updateにタスクをロードするため、そして、最初の2は、同一です。

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

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 
2

存在しないupdate_attributesにparams [:task]を渡しています。試してみてください:

params[:task] = {:done => !(@task.done)} 
+0

Doh。明らかに十分な注意を払っていない。私は私の質問がまだ立っていると思う、それを正当な "レールの道"ですか? – Soup

+0

私はあなたのようにやっていると思いますが、私の答えで指摘したように、必要なデータベース要求が増えています。 – klump

+0

それでは、DRY方法は、一般的なコードを自分のメソッドに入れて、代わりにそれらを呼び出すことです。 – klump

関連する問題