Rails: кнопки Multi-submit в одной форме
Скажем, у меня есть модель статьи, и в статье "новый" вид у меня есть две кнопки: "Опубликовать" и "Сохранить черновик".
Мой вопрос: как узнать, какая кнопка нажата в контроллере.
У меня уже есть решение, но я думаю, что должен быть лучший способ.
В настоящее время я использую в представлении:
<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. Поскольку эти кнопки находятся в одной и той же форме, все они идут в действие "create", и это нормально для меня. Я хочу обработать это в действии create, например, предоставить модели статьи столбец "статус" и удерживать "public" или "draft".
Ответы
Ответ 1
Это было описано в эпизоде 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
Ответ 2
Мы решили использовать расширенные ограничения в рельсах.
Идея состоит в том, чтобы иметь один и тот же путь (и, следовательно, один и тот же маршрут и действие), но с ограничениями, связанными с различными действиями.
resources :plan do
post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end
CommitParamRouting
- это простой класс, который имеет метод matches?
, который возвращает true, если параметр commit соответствует данному экземпляру attr. значение.
Это доступно как драгоценный камень commit_param_matching.
Ответ 3
это также можно сделать с помощью помощника 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
Ответ 4
Я помню, как однажды наткнулся на эту проблему. Вы не можете сохранить две кнопки, а затем вызвать какое-то действие на основе параметров [: commit]. кнопка submit onclick будет вызывать URL-адрес, на который ссылается форма. Есть определенные плохие способы получить желаемое поведение. Держите кнопку, чтобы вызвать действие, на которое ссылается форма, и чтобы получить другую кнопку для вызова действия, я использовал link_to, а затем изменил стили в соответствии с кнопкой. Кроме того, в качестве альтернативы вы можете использовать jQuery для изменения URL-адреса, который должна вызывать форма, поэтому решаете, какое действие вызывается во время выполнения. Надеюсь, это поможет.
Ответ 5
Вы также можете установить некоторые атрибуты data
на кнопках отправки и использовать JavaScript для изменения действия form
при щелчке одной из кнопок
Ответ 6
обычно я использую предложение Джона Толли (см. ответ выше).
другим способом является использование 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');
}