text_field rails form_with form_for form fields_for ruby-on-rails forms action

ruby on rails - rails - Rieles: botones de envío múltiple en un formulario



nested form rails (6)

Digamos que tengo un modelo de artículo, y en la vista ''nueva'' del artículo tengo dos botones, "Publicar" y "Guardar borrador".

Mi pregunta es cómo puedo saber en qué botón se hace clic en el controlador.

Ya tengo una solución, pero creo que debe haber una mejor. Lo que actualmente uso en la vista es:

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

Entonces en el controlador, puedo usar la cadena params [: commit] para manejar esa acción.

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

Pero creo que el uso de la cadena relacionada con la vista no es bueno. ¿Podrías decirme otra forma de lograr esto?

ACTUALIZACIÓN : dado que estos botones están en la misma forma, todos van a la acción ''crear'', y eso está bien para mí. Lo que quiero es manejar eso dentro de la acción de creación, como dar al modelo de artículo una columna de ''estado'' y contener ''público'' o ''borrador''.


Esto fue cubierto en el episodio 38 de Railscast . Usar el hash de params para detectar en qué botón se hizo clic es el enfoque correcto:

Ver:

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

Controlador:

if params[:create_and_add] # Redirect to new form, for example. else # Redirect to show the newly created record, for example. end


Lo resolvimos usando restricciones avanzadas en los rieles.

La idea es tener la misma ruta (y, por lo tanto, la misma ruta y acción nombradas), pero con restricciones de enrutamiento para diferentes acciones.

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

CommitParamRouting es una clase simple que tiene un método que matches? que devuelve verdadero si el param de confirmación coincide con la instancia dada attr. valor.

Esta disponible como una gema commit_param_matching .


Recuerdo haber encontrado este problema una vez. No puede mantener dos botones y luego llamar a alguna acción en función de los params [: commit]. el botón de enviar onclick llamará a la url a la que se refiere el formulario. Hay ciertas malas maneras de obtener el comportamiento deseado. Mantenga un botón para llamar a la acción a la que se refiere el formulario y para obtener otro botón para llamar a una acción, utilicé un link_to y luego cambié los estilos para que coincida con un botón. Además, como alternativa, puede usar jQuery para cambiar la URL a la que llamaría el formulario, por lo tanto, decida qué acción se invoca en el tiempo de ejecución. Espero que esto ayude.


También puede establecer algunos atributos de data en los botones de envío y usar JavaScript para cambiar la acción del form al hacer clic en uno de los botones


también se puede hacer en form_for helper como este

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

y la lógica es la misma en el controlador

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


usualmente estoy usando la sugerencia dada por John Topley (ver respuesta arriba). Otra forma es usar JQuery / JS cambiando el atributo de acción de formulario al hacer clic en el botón de enviar ejemplo:

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

y entonces .....

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