Rails:在一个表单中多重提交按钮

发布于 2024-09-11 17:32:10 字数 698 浏览 1 评论 0原文

假设我有一个文章模型,在文章“新”视图中我有两个按钮:“发布”和“保存草稿”。

我的问题是如何知道在控制器中单击了哪个按钮。

我已经有了解决方案,但我认为必须有更好的方法。 我当前在视图中使用的是:

<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

但我认为使用视图相关字符串不好。你能告诉我另一种方法来完成这个任务吗?

更新:由于这些按钮的形式相同,它们都将执行“创建”操作,这对我来说没问题。我想要的是在创建操作中处理这个问题,例如为文章模型提供一个“状态”列并保留“公共”或“草稿”。

Say I have an Article model, and in the article 'new' view I have two buttons, "Publish" and "Save Draft".

My question is how can I know which button is clicked in the controller.

I already have a solution but I think there must be a better way.
What I currently used in the view is:

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

So in the controller, I can use the params[:commit] string to handle that action.

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

  @article.save
end

But I think using the view related string is not good. Could you tell me another way to accomplish this?

UPDATE: Since these buttons are in the same form, they're all going to the 'create' action, and that's OK for me. What I want is to handle that within the create action, such as give the Article model a 'status' column and holds 'public' or 'draft'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

风为裳 2024-09-18 17:32:10

Railscast 第 38 集对此进行了介绍。使用 params 哈希来检测单击了哪个按钮是正确的方法:

View:

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

Controller:

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

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

This was covered in Railscast episode 38. Using the params hash to detect which button was clicked is the correct approach:

View:

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

Controller:

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

else
  # Redirect to show the newly created record, for example.
end
俏︾媚 2024-09-18 17:32:10

它也可以在 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

it can also be done on the form_for helper like this

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

and the logic is the same on the controller

   if params[:publish]
      // your code
   elsif params[:draft]
      // your code
   end
情话已封尘 2024-09-18 17:32:10

我们在 Rails 中使用高级约束来解决。

这个想法是具有相同的路径(因此具有相同的命名路由和操作),但具有路由到不同操作的约束。

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

CommitParamRouting 是一个简单的类,它有一个 matches? 方法,如果提交参数与给定的实例属性匹配,该方法将返回 true。价值。

这可以作为 gem commit_param_matching 获得。

We solved using advanced constraints in rails.

The idea is to have the same path (and hence the same named route & action) but with constraints routing to different actions.

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

CommitParamRouting is a simple class that has a method matches? which returns true if the commit param matches the given instance attr. value.

This available as a gem commit_param_matching.

冷弦 2024-09-18 17:32:10

我记得曾经遇到过这个问题。您不能保留两个按钮,然后根据 params[:commit] 调用某些操作。提交按钮 onclick 将调用表单引用的 url。有一些不好的方法来获得所需的行为。保留一个按钮来调用表单引用的操作,并让另一个按钮来调用操作,我使用了 link_to,然后更改了样式以匹配按钮。另外,您也可以使用 jQuery 更改表单将调用的 url,从而决定在运行时调用什么操作。希望这有帮助。

I remember coming across this problem once. You cannot keep two buttons and then call some action based on the params[:commit]. the submit button onclick is going to call the url the form refers to. There are certain bad ways to get the desired behavior. Keep a button to call the action the form refers to and to get another button to call a action, I used a link_to and then changed the styles to match a button. Also, alternatively you can use jQuery to change the url the form would call, hence deciding what action is invoked at run-time. Hope this helps.

巾帼英雄 2024-09-18 17:32:10

您还可以在提交按钮上设置一些 data 属性,并使用 JavaScript 更改单击其中一个按钮时的 form 操作

You could also set some data attributes on the submit buttons and use JavaScript to change out the form action on click of one of the buttons

人生戏 2024-09-18 17:32:10

通常我使用约翰·托普利(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');
}   

usually i using the suggestion given by John Topley (see answer above).
another way is using JQuery /JS changing the form action attribute- upon clicking the submit button
example:

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

and then .....

function changeAction(){
   $('#reports_action').attr('action','my_new_action');
}   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文