динамический флажок с использованием field_for в рельсах - PullRequest
1 голос
/ 30 марта 2010

У меня есть связь «многие ко многим» с блоком ссылок, и я хочу объединить эти модели в одну форму, чтобы я мог обновляться с одной страницы. Я действительно изо всех сил пытаюсь заставить 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: {}

Любая помощь очень ценится.

Ответы [ 3 ]

2 голосов
/ 30 марта 2010

Крейг, это звучит так, как будто вы ищете, является accepts_nested_attributes_for, который является гораздо лучшим способом обработки вложенных моделей в форме.

Вместо того, чтобы просто украсть все работы Райана и опубликовать их здесь, я просто дам вам ссылку на его скринкаст:

http://railscasts.com/episodes/196-nested-model-form-part-1

Это основано на его серии сложных форм.

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

EDIT:

Хорошо, после просмотра вашего кода, есть несколько вещей, вызывающих у вас проблемы. :)

Прежде всего, с ассоциациями вам не нужно тянуть дополнительную коллекцию для выставления счетов, т. Е .:

@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 %>

Так что, возможно, уточнить, что вы пытаетесь достичь с точки зрения функциональности, и мы сможем найти лучшее решение.

0 голосов
/ 30 марта 2010

Мне кажется, это проблема с циклами for ...

В вашем примере кода вы перебираете @billings (массив объектов выставления счетов, переданных с вашего контроллера) и вызываете текущий billing.

В коде формы вы перебираете :billings (символ, относящийся к биллингу ActiveRecords) и вызываете текущий obj. Затем, что сбивает с толку, ваш код повторно использует имя переменной obj снова в функции @ billings.collect ... но это должно иметь локальную частную область видимости и не влиять на ваш основной цикл, но это трудно интерпретировать на виду.

В любом случае, поскольку содержимое внутри цикла формы не ссылается на obj, оно использует переменную billing - которая не изменяется при цикле, но сохраняет последнее значение: последний элемент из предыдущего цикла! Это объясняет, почему вы видите только последний тег. (Кроме того, функция debug(@billings) выполняет собственный цикл сортировки записей - она ​​не находится внутри цикла fields_for do.)

Я бы начал с изменения первой строки кода вашей формы, чтобы снова использовать имя переменной billing, например:

<% f.fields_for :billings do |billing| %><br />

Синтаксис блока Ruby поначалу может быть довольно запутанным - или, черт возьми, всякий раз, когда вы читаете код, который вы не написали сами - но когда вы разбиваете все это на основные компоненты, обычно это просто циклический просмотр набора элементов и выполнение некоторых функций для каждого из них. Также следите за путаницей между похожими именами: @billing, @billings,: billings и billings - это разные вещи для Ruby и Rails. Удачи!

0 голосов
/ 30 марта 2010

Я не уверен в своем ответе, но я попробую ...

<% f.fields_for :billings, @billings do |obj| %>
   # ...
<% end %>
...