複数の送信ボタンが必要です。
Contact_Callのインスタンスを作成するフォームがあります。
1つのボタンで通常どおり作成されます。
もう1つのボタンはそれを作成しますが、デフォルトとは異なる:attribute値を持つ必要があり、コントローラーで使用される別の関連するモデルに属性を設定する必要もあります。
それ、どうやったら出来るの?ルートを変更できないので、[:params]によって取得される別の変数を送信する方法はありますか?
そして、その場合、コントローラーで何をし、caseステートメントを設定しますか?
複数の送信ボタンを作成し、それぞれに異なる値を提供できます。
<% form_for(something) do |f| %>
..
<%= f.submit 'A' %>
<%= f.submit 'B' %>
..
<% end %>
これは出力します:
<input type="submit" value="A" id=".." name="commit" />
<input type="submit" value="B" id=".." name="commit" />
コントローラー内では、送信されたボタンの値はパラメーターcommit
によって識別されます。値を確認して、必要な処理を実行します。
def <controller action>
if params[:commit] == 'A'
# A was pressed
elsif params[:commit] == 'B'
# B was pressed
end
end
ただし、これにより、ビューがコントローラーに緊密に結合されることに注意してください。
また、送信ボタンでformaction属性を使用する別のアプローチもあります。
<% form_for(something) do |f| %>
...
<%= f.submit "Create" %>
<%= f.submit "Special Action", formaction: special_action_path %>
<% end %>
標準の作成ボタンは変更する必要がないため、コードはクリーンなままです。特別なボタンのルーティングパスを挿入するだけです。
formaction:
入力要素が送信ボタンまたは画像である場合、入力要素によって送信された情報を処理するプログラムのURI。指定されている場合、要素のフォームの所有者のアクション属性をオーバーライドします。ソース: [〜#〜] mdn [〜#〜]
または、どのボタンが押されたかを認識して、属性名を変更できます。
<% form_for(something) do |f| %>
..
<%= f.submit 'A', name: 'a_button' %>
<%= f.submit 'B', name: 'b_button' %>
..
<% end %>
params[:commit]
値を単にチェックするのではなく、paramsキーの存在をチェックする必要があるため、少し不快です。どちらが押されたかに応じてparams[:a_button]
またはparams[:b_button]
を受け取ります。
Gemを使用せずに@ vss123によって提案されたものと同様のソリューション:
resources :plan do
post :save, constraints: lambda {|req| req.params.key?(:propose)}, action: :propose
post :save, constraints: lambda {|req| req.params.key?(:finalize)}, action: :finalize
end
多くの場合、送信ボタンの値は国際化/翻訳されているため、値の使用を避け、代わりに入力名を使用しています。また、ルートファイルがすぐに乱雑になるため、これを使いすぎないようにします。
Railsで 高度な制約 を使用して解決しました。
考え方は同じパス(したがって同じ名前のルートとアクション)を持ち、制約は異なるアクションにルーティングすることです。
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting
は、matches?
メソッドを持つ単純なクラスです。このメソッドは、コミットパラメーターが指定されたインスタンスattrに一致する場合にtrueを返します。値。
これはgem commit_param_matching として利用可能です。
古い質問ですが、同じ状況に対処しているので、解決策を投稿すると思いました。コントローラーロジックとビューボタンの間に矛盾が生じないように、コントローラー定数を使用しています。
class SearchController < ApplicationController
SEARCH_TYPES = {
:searchABC => "Search ABCs",
:search123 => "Search 123s"
}
def search
[...]
if params[:commit] == SEARCH_TYPES[:searchABC]
[...]
elsif params[:commit] == SEARCH_TYPES[:search123]
[...]
else
flash[:error] = "Search type not found!"]
[...]
end
end
[...]
end
そして、ビューで:
<% form_for(something) do |f| %>
[...]
<%= f.submit SearchController::SEARCH_TYPES[:searchABC] %>
<%= f.submit SearchController::SEARCH_TYPES[:search123] %>
[...]
<% end %>
このように、テキストは1つの場所にのみ存在します-コントローラーの定数として。ただし、これをどのようにi18nするかについてはまだ考えていません。
Nested_form_fieldsのおかげでフォーム上に可変数の送信ボタンがあるため、名前を使用するだけでは十分ではありませんでした。最終的にフォームに非表示の入力フィールドを含め、フォーム送信ボタンの1つが押されたときにJavascriptを使用して入力しました。