Подтвердить что ты не робот

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-адрес в названии ссылки, дополнительные значения clobber друг друга:

<%= hidden_field_tag "article[links]", :track, :value => url %>

Результат выглядит следующим образом: "links" => "http://stackoverflow.com"

4b9b3361

Ответ 1

Если ваша форма html имеет поля ввода с пустыми квадратными скобками, они будут преобразованы в массив внутри параметров в контроллере.

# 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

Добавлено:

Обратите внимание, что помощники рельсов не настроены на автоматическое магнетическое трюк. Поэтому вам, возможно, придется вручную создавать атрибуты имени. Кроме того, флажки имеют свои проблемы при использовании помощников рельсов, поскольку хелпер-флажок создает дополнительные скрытые поля для обработки непроверенного случая.

Ответ 2

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

Ответ 3

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">

Получены парамы:

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

Hash

<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">

Получены парамы:

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

Ответ 4

Я также узнал, что если вы передадите свой вспомогательный помощник, вы получите массив курсов, каждый со своими атрибутами.

# 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    

Ответ 5

Я просто установил решение, используя 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

Ответ 6

Для тех, кто использует простую форму, вы можете рассмотреть это решение. В основном необходимо настроить свой собственный вход и использовать его как: array. Затем вам нужно будет обрабатывать ввод на уровне вашего контроллера.

#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 в поле вашего массива