web-dev-qa-db-ja.com

Rails:1つのフォームに複数送信ボタン

記事モデルがあり、記事の「新規」ビューに「公開」と「下書きを保存」の2つのボタンがあるとします。

私の質問は、どのボタンがコントローラーでクリックされたかをどのように知ることができるかです。

私はすでに解決策を持っていますが、もっと良い方法があるに違いないと思います。ビューで現在使用しているのは:

<div class="actions">
  <%= f.submit "Publish" %>
  <%= f.submit "Save Draft", :name => "commit" %>
</div>

そのため、コントローラーでは、params [:commit]文字列を使用してそのアクションを処理できます。

def create
  @article = Article.new(params[:article])
  if params[:commit] == "Publish"
    @article.status = 'publish'
    // detail omitted
  end

  @article.save
end

しかし、ビューに関連する文字列を使用するのは良くないと思います。これを達成する別の方法を教えてください。

[〜#〜] update [〜#〜]:これらのボタンは同じ形式であるため、すべて「作成」アクションに移動しますが、それは問題ありません。私が望むのは、記事モデルに「ステータス」列を与え、「パブリック」または「ドラフト」を保持するなど、作成アクション内でそれを処理することです。

59
kinopyo

これは Railscastエピソード38 で説明されていました。 paramsハッシュを使用して、クリックされたボタンを検出するのが正しいアプローチです。

表示:

<%= submit_tag 'Create' %>
<%= submit_tag 'Create and Add Another', name: 'create_and_add' %>

コントローラー:

if params[:create_and_add]
  # Redirect to new form, for example.

else
  # Redirect to show the newly created record, for example.
end
64
John Topley

Railsで 高度な制約 を使用して解決しました。

考え方は同じパス(したがって同じ名前のルートとアクション)を持ち、制約は異なるアクションにルーティングすることです。

resources :plan do
  post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
  post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end

CommitParamRoutingは、コミットパラメータが指定されたインスタンスattrに一致する場合にtrueを返すメソッドmatches?を持つ単純なクラスです。値。

これはgem commit_param_matching として利用可能です。

7
siliconsenthil

このようにform_forヘルパーで行うこともできます

 <%= f.submit "Publish",name: "publish", class: "tiny button radius success" %>
 <%= f.submit 'Mark as Draft', name: "draft", class: "tiny button radius " %>

ロジックはコントローラー上で同じです

   if params[:publish]
      // your code
   elsif params[:draft]
      // your code
   end
6
Petros Kyriakou

この問題に一度遭遇したことを覚えています。 2つのボタンを保持してから、params [:commit]に基づいてアクションを呼び出すことはできません。送信ボタンonclickは、フォームが参照するURLを呼び出します。望ましい動作を得るための特定の悪い方法があります。フォームが参照するアクションを呼び出すボタンを保持し、アクションを呼び出す別のボタンを取得するには、link_toを使用し、ボタンに合わせてスタイルを変更しました。また、代わりにjQueryを使用して、フォームが呼び出すURLを変更し、実行時にどのアクションを呼び出すかを決定できます。お役に立てれば。

1
Alok Swain

送信ボタンにいくつかのdata属性を設定し、JavaScriptを使用してボタンのいずれかをクリックしたときにformアクションを変更することもできます。

0
dennismonsewicz

通常、John Topleyからの提案を使用します(上記の回答を参照)。別の方法は、JQuery/JSを使用してフォームアクション属性を変更することです。送信ボタンの例をクリックすると:

form_tag({} ,:method => 'post', :id => 'reports_action') do 
   .......
   ....... 
  submit_tag 'submit',  :onclick => "return changeAction();"
end

その後 .....

function changeAction(){
   $('#reports_action').attr('action','my_new_action');
}   
0
yonatan