динамический флажок_box с использованием field_for в рельсах
-
23-09-2019 - |
Вопрос
У меня есть связь «многие ко многим» с полем ссылки, и я хочу объединить эти модели в одну форму, чтобы можно было обновлять их с одной и той же страницы.Я действительно изо всех сил пытаюсь заставить check_box отображать все элементы моего массива - я рыскал в сети и работал над этим буквально весь день, и мне трудно применить информацию, которую я читаю. моя проблема.Я также новичок в RoR и следую устаревшему видеоуроку (до версии 2.0), поэтому прошу прощения за мой код.Пока что у меня получилось выводить только одну пару ключей в массиве (последнюю) — хотя вне формы код, использованный в туториале, работает именно так, как надо.Хотя от этого мало толку!Хост — это модель, для которой предназначена основная форма, а Биллинг — это внешняя модель, которую я пытаюсь добавить в форму.
Это код, который работает вне формы из руководства:
<% for billing in @billings -%>
<%= check_box_tag('billing_title[]', billing.id, @host.billings.collect
{|obj| obj.id}.include?(billing.id))%> <%= billing.title %><br />
<% end -%>
Мне просто нужно знать, как заставить это работать внутри формы.Это вышеупомянутый код, который извлекает только последнюю пару ключей массива после их прохождения:
<% f.fields_for :billings do |obj| %><br />
<%= check_box_tag('billing_title[]', billing.id, @billings.collect
{|obj| obj.id}.include?(billing.id))%> <%= billing.title %><br />
<% end %>
Отладка(@billings):
---
- !ruby/object:Billing
attributes:
title: Every Month
id: "1"
attributes_cache: {}
- !ruby/object:Billing
attributes:
title: 12 Months
id: "2"
attributes_cache: {}
- !ruby/object:Billing
attributes:
title: 6 Months
id: "5"
attributes_cache: {}
Любая помощь действительно ценится.
Решение
Крейг, похоже, что вы ищете Accepts_nested_attributes_for, который является гораздо лучшим способом обработки вложенных моделей в форме.
Вместо того, чтобы просто украсть все работы Райана и перепостить их здесь, я просто дам вам ссылку на его скринкаст:
http://railscasts.com/episodes/196-nested-model-form-part-1
Это основано на его серии сложных форм.
У вас должна быть возможность адаптировать это руководство к тому, что вы пытаетесь сделать, но если нет, я буду рад помочь.
РЕДАКТИРОВАТЬ:
Хорошо, после просмотра вашего кода есть несколько вещей, вызывающих у вас проблемы.:)
Во-первых, с ассоциациями не нужно тянуть лишний сбор для биллинга, т.е.:
@host = Host.find(params[:id])
@voips = Voip.find(:all)
@custsupps = Custsupp.find(:all)
@payments = Payment.find(:all)
@billings = Billing.find(:all) # <-- This is not needed and causing your problems
Настройка ассоциации в модели сделает все это за вас.Это часть магии рельсов.:D
Теперь важно отметить, что при использовании ассоциаций необходимо убедиться, что объекты действительно связаны.Другими словами, если в вашей базе данных есть 3 объекта Billings, и они не связаны с вашим объектом Host, они не будут отображаться в форме.
Если вы пытаетесь связать биллинг с хостом с помощью флажка, вам придется использовать другой подход, потому что ваша форма отображает только счета. уже связан с вашим Хозяином.
Если вы просто пытаетесь отредактировать или изменить существующие счета, связанные с хостом, где флажок представляет, например, «оплаченный» атрибут (логическое значение), тогда этот подход подойдет, и код вашей формы будет выглядеть примерно так:
<% f.fields_for :billings do |b| %><br />
<%= b.check_box :paid %> <%= b.title %>
<% end %>
Поэтому, возможно, уточните, чего вы пытаетесь достичь с точки зрения функциональности, и мы сможем найти лучшее решение.
Другие советы
не уверен в своем ответе, но попробую...
<% f.fields_for :billings, @billings do |obj| %>
# ...
<% end %>
Мне кажется, это проблема с циклами for...
В вашем примере кода вы проходите через @billings
(массив объектов биллинга, переданных от вашего контроллера) и вызов текущего billing
.
В коде вашей формы вы проходите через :billings
(символ, ссылающийся на ActiveRecords биллинга) и вызов текущего obj
.Затем, что сбивает с толку, ваш код повторно использует имя переменной. obj
снова в функции @billings.collect...но это должно иметь локальную частную область действия и не влиять на ваш основной цикл, но это трудно интерпретировать с первого взгляда.
В любом случае, поскольку материал внутри вашего цикла формы не ссылается obj
, он использует переменную billing
--который не меняется при прохождении цикла, но сохраняет последнее значение, которое оно имело:последний элемент предыдущего цикла!Это объясняет, почему вы видите только последний тег.(Так же debug(@billings)
Функция выполняет свой собственный цикл по различным записям — она не находится внутри цикла field_for do.)
Я бы начал с изменения первой строки кода вашей формы, чтобы повторно использовать имя переменной. billing
еще раз вот так:
<% f.fields_for :billings do |billing| %><br />
Синтаксис блоков Ruby поначалу может быть довольно запутанным — или, черт возьми, каждый раз, когда вы читаете код, который вы писали не сами — но когда вы разбиваете все это на базовые компоненты, обычно это просто циклический просмотр набора элементов и выполнение некоторых функция на каждом из них.Также обратите внимание на путаницу между похожими именами:@billing, @billings, :billings и billings — это разные вещи для Ruby и Rails.Удачи!