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"

711   6  

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

    Ничего не найдено.