Ruby on Rails: отправка массива в форме
у меня есть модель, которая имеет атрибут, который является массивом. Каков правильный способ для меня заполнить этот атрибут из представления формы?
Я знаю, что ввод формы с полем, имя которого включает скобки, создает хэш из ввода. Должен ли я просто взять это и пройти через него в контроллере, чтобы массажировать его в массив?
пример, чтобы сделать его менее абстрактным:
class Article
serialize :links, Array
end
переменной ссылки в виде URL-адресов, то есть [["http://www.google.com"], ["http://stackoverflow.com"]]
когда я использую что-то вроде следующего в моей форме, он создает хэш:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>
результирующий хэш выглядит так:
"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}
если я не включаю url В имя ссылки, дополнительные значения колотят друг друга:
<%= hidden_field_tag "article[links]", :track, :value => url %>
результат выглядит так: "links" => "http://stackoverflow.com"
6 ответов:
Если Ваша html-форма имеет поля ввода с пустыми квадратными скобками, то они будут превращены в массив внутри params в контроллере.
# 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добавлено:
обратите внимание, что рельсы помощники не настройка для автоматического выполнения трюка с массивом. Так что вам, возможно, придется создать имя атрибуты вручную. Кроме того, флажки имеют свои собственные проблемы при использовании помощников rails, поскольку помощники флажка создают дополнительные скрытые поля для обработайте непроверенный случай.
= simple_form_for @article do |f| = f.input_field :name, multiple: true = f.input_field :name, multiple: true = f.submit
TL; DR версия HTML
[]конвенции:время:
<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 получено:
{ course: { track_codes: ['a', 'b', 'c'] } }хэш
<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 получено:
{ course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
Я также узнал, что если входные данные помощника, как это вы получите массив курсов, каждый с собственными атрибутами.
# 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
Я просто настроил решение с помощью jQuery taginput:
http://xoxco.com/projects/code/tagsinput/
Я написал расширение 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фрагмент coffeescrpt:
$('input.tag').tagsInput()и настройка моего контроллера, который, к сожалению, должен быть немного конкретным:
@user = User.find(params[:id]) attrs = params[:user] if @user.some_field.is_a? Array attrs[:some_field] = attrs[:some_field].split(',') end
для тех, кто использует простую форму, вы можете рассмотреть это решение. В принципе нужно создать свой собственный вход и использовать его как массив. Тогда вам нужно будет обрабатывать ввод на уровне контроллера.
#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в вашем случае просто измените: premium_keyword на поле вашего массива
Comments