Показывать список флажков вместо нескольких

У меня есть модель MyModel с сериализованным атрибутом a, описывающим массив символов.

Этот код работает:

<% form_for @my_model do |f| %>
  <%= f.select :a, MyModel::AS, :multiple => true) %>
<% end %>

Параметры верны:

{ :my_model => { :a => [:a_value1, :a_value2] } }

Я хочу преобразовать этот множественный выбор в набор флажков, например:

<% form_for @my_model do |f| %>
  <% MyModel::AS.each do |a_value|
    <%= f.check_box(:a_value) %>
  <% end %>
<% end %>

Он работает тоже, но параметры не одинаковы:

{ :my_model => { :a_value1 => 1, :a_value2 => 1 } }

Я думаю о 2 решениях для возврата к первому решению...

  • Преобразуйте my check_box в check_box_tag, замените множественный выбор и добавьте некоторый javascript для "проверки", чтобы выбрать значения, когда пользователь кликает по check_box_tags. Затем параметр будет таким же непосредственно в контроллере.
  • Добавить код litte в контроллер для "адаптации" моих параметров.

Какое решение менее уродливое? Или есть другой?

Ответ 1

Я нашел решение, используя параметр "multiple", который я не знал.

<% MyModel::AS.each do |a_value| %>
  <%= f.check_box(:a, { :multiple => true }, a_value) %>
<% end %>

Параметры результата немного странные, но они должны работать.

{"my_model" => { "a" => ["0", "a_value1", "0", "a_value2", "0"] }

Изменить из @Viren: передать nil в конце функции, например

  <%= f.check_box(:a, { :multiple => true }, a_value, nil) %>

отлично работает.

Ответ 2

Вы можете сделать это следующим образом:

<% MyModel::AS.each do |a_value| %>
  <%= f.check_box("a[]", a_value) %>  
<% end %>

Это приведет к тому, что параметры появятся на сервере следующим образом

{ :my_model => { :a => [:a_value1, :a_value2] } }

Ответ 3

Есть и другое решение, которое стоит упомянуть, что очень легко вставить записи в базу данных, если у вас есть отношения has_and_belongs_to_many или has_many through с помощью хелпера collection_check_boxes.

<%= f.collection_check_boxes :mymodel_ids, MyModel::AS, :id, :name do |m| %>
  <%= m.check_box %> <%= m.label %>
<% end %>

Затем в контроллере мы допустим атрибут mymodel_ids:

params.require(:mymodel).permit(:name, mymodel_ids:[])

Мы также можем настроить валидацию модели, чтобы потребовалось проверить хотя бы один из флажков:

validates :mymodel_ids, presence: true

Дополнительным преимуществом этого метода является то, что если вы позже отредактируете запись mymodel и снимите флажок с одного из этих флажков, его запись будет удалена из таблицы связей many_to_many на save.