Ruby on Rails: отправка массива в форме - PullRequest
64 голосов
/ 22 июня 2010

У меня есть модель с атрибутом Array.Как мне правильно заполнить этот атрибут из представления формы?

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

Пример, чтобы сделать его менее абстрактным:

class Article
  serialize :links, Array
end

Переменная links принимает формумассив 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 ]

88 голосов
/ 22 июня 2010

Если ваша 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

Добавлено:

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

50 голосов
/ 31 января 2014
= simple_form_for @article do |f|
  = f.input_field :name, multiple: true
  = f.input_field :name, multiple: true
  = f.submit
38 голосов
/ 27 ноября 2015

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'] } }

Хеш

<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' } }
8 голосов
/ 27 июля 2013

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

# 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    
7 голосов
/ 08 февраля 2013

Я только что создал решение, используя 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
0 голосов
/ 05 марта 2014

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

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

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