Вопрос по ruby-on-rails, params, checkbox, ruby-on-rails-3 – Как я могу сделать check_box_tag, чтобы публиковать параметр 'false' или '0', когда не отмечен?

33

Со следующим check_box_tag:

<code><%= check_box_tag 'object[boolean_attribute]', 1, object.boolean_attribute %>
</code>

Я могу обновить boolean_attribute только в одном направлении: от false до true.

Когда по умолчанию флажок снят (поскольку object.boolean_attribute имеет значение false), я проверяю его и затем отправляю форму, a: boolean_attribute = & gt; 1 параметр опубликован.

But, когда я пытаюсь обновить с true на false, никакие параметры не передаются, поэтому boolean_attribute остается true.

Другими словами, когда установлен флажок по умолчанию (потому что object.boolean_attribute имеет значение true), и я снимаю флажок и затем отправляю форму, a: boolean_attribute = & gt; 0 этоnot вывешенный.

Как я могу сделать этот check_box_tag, чтобы опубликовать: boolean_attribute = & gt; 0 параметр когда не проверен?

Из API я не могу понять, есть ли какой-то вариант, чтобы легко его достичь: http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-check_box_tag

Спасибо.

EDIT

По какой-то причине я не могу понять, в моем реальном коде (с вложенной ассоциацией «многие ко многим») hidden_field_tag не работает.

<code><%= hidden_field_tag 'order[preparations_attributes][][cooked]', nil %>
<%= check_box_tag 'order[preparations_attributes][][cooked]', '1', preparation.cooked? %>
</code>

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

Вот опубликованные параметры для непроверенной коробки:

<code>Parameters: {"utf8"=>"✓", "authenticity_token"=>"bGgPGbk+Cuk2q+LEgqetmk4e7xie8dB3iMP9Cj3SUm0=", "order"=>{"customer_name"=>"Duccio Armenise", "duedate"=>"2012-04-25 09:24:00.000000", "preparations_attributes"=>[{"quantity"=>"1", "description"=>"custom recipe", "kind"=>"custom", "cooked"=>"", "recipe_id"=>"9", "id"=>"86", "quantities_attributes"=>[{"ingredient_id"=>"", "qty"=>"", "_destroy"=>"0"}, {"ingredient_id"=>"11", "qty"=>"5.0", "id"=>"193", "_destroy"=>"0"}], "_destroy"=>"0"}], "add_preparation"=>{"recipe_id"=>""}}, "continue"=>"Confirm", "id"=>"31"}
</code>

Теперь посмотрим, что за беспорядок, когда я поставлю галочку, начиная с "cooked" = & gt; & quot; & quot ;, по какой-то причине Rails слишком рано закрывает хэш prepare_attributes!

<code>Parameters: {"utf8"=>"✓", "authenticity_token"=>"bGgPGbk+Cuk2q+LEgqetmk4e7xie8dB3iMP9Cj3SUm0=", "order"=>{"customer_name"=>"Duccio Armenise", "duedate"=>"2012-04-25 09:24:00.000000", "preparations_attributes"=>[{"quantity"=>"1", "description"=>"custom recipe", "kind"=>"custom", "cooked"=>""}, {"cooked"=>"1", "recipe_id"=>"9", "id"=>"86", "quantities_attributes"=>[{"ingredient_id"=>"", "qty"=>"", "_destroy"=>"0"}, {"ingredient_id"=>"11", "qty"=>"5.0", "id"=>"193", "_destroy"=>"0"}], "_destroy"=>"0"}], "add_preparation"=>{"recipe_id"=>""}}, "continue"=>"Confirm", "id"=>"31"}
</code>

EDIT #2:

Я думаю, что столкнулся с ошибкой Rails, связанной с глубоко вложенными формами ресурсов и передачей параметров:https://github.com/rails/rails/issues/5937

На данный момент я сделал это для работы с select_tag:

<code><%= select_tag 'order[preparations_attributes][][cooked]', options_for_select({yes: 1, no: 0}, preparation.cooked? ? 1 : 0) %> 
</code>

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

В любом случае, спасибо за ответы!

Ваш Ответ

5   ответов
0

= hidden_field_tag "ad_ids[#{ad.token}]" , false
= check_box_tag "ad_ids[#{ad.token}]" , true, true
1

уг истинного и ложного.

Оригинальный код

<%= f.check_box :admin, {}, true, false %>

Обновленный код

<%= f.check_box :admin, {}, 'true', 'false' %>

Я надеюсь, что это помогает кому-то еще!

27

<%= hidden_field_tag 'object[boolean_attribute]', nil %>

Таким образом, даже если ваш флажок не установлен, вы все равно получитеnil Отправлено. Будет ли это работать для вас?

Я просто играл с этим, и это прекрасно работает, мой контроллер получает параметры, которые я хочу. Однако это не помогло моим тестам, потому что теперь Capybara не может найти этот флажок, поскольку есть два флажка с одинаковым идентификатором. Я собираюсь попытаться нацелить его по-другому, но кажется, что делать что-то вроде этого, когда вы получаете два одинаковых идентификатора на одной странице, немного хакерски.
Есть более удобный подход. Смотри мой ответ.
Прекрасно, мне это нравится.
Спасибо, я знал этот подход, я за другим, потому что по какой-то причине в моем реальном приложении это не работает (у меня есть несколько вложенных моделей многие-ко-многим ...). Я обновляю вопрос своим реальным кодом ... Darme
Вы также можете проверить, действительно ли вы хотите, чтобы капибара предназначалась для скрытых полей. Если нет, вы можете установить в своем spec_helper.rb или его эквиваленте: Capybara.ignore_hidden_elements = false
6

Если у кого-то есть тип столбца логический и используетсяcheck_box_tag тогда посмотри на это. Это сработало для меня. <%= hidden_field_tag 'order[preparations_attributes][][cooked]', 'false' %> <%= check_box_tag 'order[preparations_attributes][][cooked]', true, preparation.cooked? %>

46

check_box (Ж / о_tag) помощник добавляет скрытое поле для решения вашей проблемы для вас:

%= check_box 'object', 'boolean_attribute', {}, 'true', 'false' %>

# result:
;input name="object[boolean_attribute]" type="hidden" value="false" />
;input id="object_boolean_attribute" name="object[boolean_attribute]" type="checkbox" value="true" />

UPD: Работа с вложенными ресурсами (продуктaccepts_nested_attributes_for :позиции)

= form_for @product, url: '' do |f|
  %p
    = f.label :title
    = f.text_field :title

  = f.fields_for :line_items do |li|
    = li.check_box :approved
    = li.label :approved, li.object.id
    %br
  = f.submit

Проверка 2 из 3 флажков дает мнеparams как это:

{..., & quot; product & quot; {& quot; title & quot; = & gt; & quot; RoR book & quot ;, & quot; line_items_attributes & quot; = & gt; {& quot; 0 & quot; = & gt; {& quot; = & quot; = & quot; = & quot; = & gt; ; 0 "," id "= =" 47 "}," 1 "= =" утверждено "=" 1 "," id "=" 48 ", "2" = "утвержден" = "1", "идентификатор" = "51"}}, "зафиксировать" = "обновить продукт", "обновить" действие "=" действие 1 "," контроллер "=" проверка "}

params как YAML для удобочитаемости:

product:
  title: RoR book
  line_items_attributes:
    '0':
      approved: '0'
      id: '47'
    '1':
      approved: '1'
      id: '48'
    '2':
      approved: '1'
      id: '51'

Увидеть? Нет скрытых полей, но отмеченные / непроверенные состояния четко различимы.

Имея этоparams позволяет мне использовать одну строку кода для обновления связанных line_items:

@product.update_attributes params[:product]

Я надеюсь, что это помогает.

Да, это подходит! Ничто не мешает вам передать что-то вроде'order[preparations_attributes][][cooked]' вместо'object'.
На данный момент я сделал обходной путь к решению select_tag (см. РЕДАКТИРОВАТЬ # 2), но я собираюсь также проверить ваше предложение ... Darme
Вы не сказали ни слова о структуре вашего приложения (о M в MVC), поэтому я не смогу быть более полезным. Давайте сделаем так: я покажу вам способ работы с вложенными ресурсами. Это классический пример: Product has_many: line_items. LineItem имеет:approved поле. Проверьте мой UDP для работы с этими полями черезcheck_box.
Спасибо, но я был после решения check_box_tag, потому что в моем реальном коде я обновляю вложенный ресурс. Смотрите мой фактический код в редактировании. Применимо ли ваше решение к форме вложенных ресурсов? Darme
Это не работает в Rails 4

Похожие вопросы