lista - Ruby on Rails: enviar una matriz en forma
imprimir matriz ruby (6)
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:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => 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í:
<%= hidden_field_tag "article[links]", :track, :value => url %>
El resultado se ve así: "links" => "http://stackoverflow.com"
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
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:
<input type="textbox" name="course[track_codes][]" ...>
# 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 rieles 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 rieles, ya que los ayudantes de casilla de verificación crean campos ocultos adicionales para manejar el caso no marcado.
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:
<input type="textbox" name="course[][track_codes]" ...>
# 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
TL; versión DR de la convención HTML []
:
Formación:
<input type="textbox" name="course[track_codes][]", value="a">
<input type="textbox" name="course[track_codes][]", value="b">
<input type="textbox" name="course[track_codes][]", value="c">
Params recibidos:
{ course: { track_codes: [''a'', ''b'', ''c''] } }
Picadillo
<input type="textbox" name="course[track_codes][x]", value="a">
<input type="textbox" name="course[track_codes][y]", value="b">
<input type="textbox" name="course[track_codes][z]", value="c">
Params recibidos:
{ course: { track_codes: { x: ''a'', y: ''b'', z: ''c'' } }
= simple_form_for @article do |f|
= f.input_field :name, multiple: true
= f.input_field :name, multiple: true
= f.submit