Ruby on Rails: enviar una matriz en forma

Tengo un modelo que tiene un atributo que es una matriz. ¿Cuál es la forma correcta de completar ese atributo desde un envío de formulario?

Sé que tener una entrada de formulario con un campo cuyo nombre incluye corchetes crea un hash a partir de la entrada. ¿Debo tomar eso y pasar por él en el controlador para masajearlo en una matriz?

Ejemplo para hacerlo menos abstracto:

class Article serialize :links, Array end 

La variable de enlaces toma la forma de una matriz de URL, es decir [["http://www.google.com"], ["http://stackoverflow.com"]]

Cuando uso algo como lo siguiente en mi formulario, crea un hash:

  nil %> 

El hash resultante se ve así:

 "links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""} 

Si no incluyo la url en el nombre del enlace, los valores adicionales se golpean entre sí:

  url %> 

El resultado se ve así: "links" => "http://stackoverflow.com"

Si su formulario html tiene campos de entrada con corchetes vacíos, se convertirán en una matriz dentro de params en el controlador.

 # Eg multiple input fields all with the same name:  # will become the Array params["course"]["track_codes"] # with an element for each of the input fields with the same name 

Adicional:

Tenga en cuenta que los helpers de los Rails no están configurados para hacer el truco de la matriz de forma automática. Por lo tanto, es posible que deba crear los atributos de nombre manualmente. Además, las casillas de verificación tienen sus propios problemas si se usan los ayudantes de Rails, ya que los ayudantes de checkbox crean campos ocultos adicionales para manejar el caso no marcado.

 = simple_form_for @article do |f| = f.input_field :name, multiple: true = f.input_field :name, multiple: true = f.submit 

TL; versión DR de la convención HTML [] :

Formación:

    

Params recibidos:

 { course: { track_codes: ['a', 'b', 'c'] } } 

Picadillo

    

Params recibidos:

 { course: { track_codes: { x: 'a', y: 'b', z: 'c' } } 

También descubrí que si pasas tu ayudante de entrada de esta manera obtendrás una serie de cursos, cada uno con sus propios atributos.

 # Eg multiple input fields all with the same name:  # will become the Array params["course"] # where you can get the values of all your attributes like this: params["course"].each do |course| course["track_codes"] end 

Acabo de configurar una solución usando jquery taginput:

http://xoxco.com/projects/code/tagsinput/

Escribí una extensión personalizada simple_form

 # for use with: http://xoxco.com/projects/code/tagsinput/ class TagInput < SimpleForm::Inputs::Base def input @builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(','))) end end 

Un fragmento de coffeescrpt:

 $('input.tag').tagsInput() 

Y un ajuste a mi controlador, que tristemente tiene que ser ligeramente específico:

 @user = User.find(params[:id]) attrs = params[:user] if @user.some_field.is_a? Array attrs[:some_field] = attrs[:some_field].split(',') end 

Para aquellos que usan formularios simples, puede considerar esta solución. Básicamente necesita configurar su propia entrada y usarla como: matriz. Entonces necesitaría manejar la entrada en su nivel de controlador.

 #inside lib/utitilies class ArrayInput < SimpleForm::Inputs::Base def input @builder.text_field(attribute_name, input_html_options.merge!({value: object.premium_keyword.join(',')})) end end #inside view/_form ... = f.input :premium_keyword, as: :array, label: 'Premium Keyword (case insensitive, comma seperated)' #inside controller def update pkw = params[:restaurant][:premium_keyword] if pkw.present? pkw = pkw.split(", ") params[:restaurant][:premium_keyword] = pkw end if @restaurant.update_attributes(params[:restaurant]) redirect_to admin_city_restaurants_path, flash: { success: "You have successfully edited a restaurant"} else render :edit end end 

En su caso, simplemente cambie: premium_keyword al campo de su matriz