Pergunta

Tenho um relacionamento muitos-para-muitos com uma caixa de link e quero reunir esses modelos em um formulário para poder atualizar na mesma página.Estou realmente lutando para fazer com que a caixa de seleção mostre todos os elementos do meu array - vasculhei a rede e trabalhei nisso literalmente o dia todo e estou achando difícil aplicar as informações que estou lendo para meu problema.Também sou extremamente novo no RoR e tenho seguido um tutorial em vídeo um pouco desatualizado (pré 2.0), então peço desculpas pelo meu código.Até agora, consegui gerar apenas um par de chaves no array (o último) - embora fora do formulário, o código usado no tutorial funciona exatamente como deveria.Isso é de pouca utilidade!Host é o modelo para o qual se destina o formulário principal e Billing é o modelo externo que estou tentando adicionar ao formulário.

Este é o código que funciona fora do formulário do tutorial:

<% for billing in @billings -%>
<%= check_box_tag('billing_title[]', billing.id, @host.billings.collect
{|obj| obj.id}.include?(billing.id))%> <%= billing.title %><br />
<% end -%>

Só preciso saber como fazer funcionar dentro do formulário.Este é o código mencionado anteriormente que recupera apenas o último par de chaves do array após percorrê-los:

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

A depuração(@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: {}

Qualquer ajuda é realmente apreciada.

Foi útil?

Solução

Craig, parece que o que você está procurando é aceita_nested_attributes_for, que é uma maneira muito melhor de lidar com modelos aninhados em um formulário.

Em vez de apenas roubar todo o trabalho de Ryan e repassar aqui, eu vou te dar um link para o screencast dele:

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

Isso se baseia em sua complexa série de formulários.

Você deve ser capaz de fazer este tutorial sobre o que está tentando fazer, mas se não ficaria feliz em ajudar.

EDITAR:

Tudo bem, depois de olhar para o seu código, há algumas coisas causando problemas. :)

Primeiro de tudo, com associações, você não precisa fazer uma coleção extra para Billings, ou seja:

@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

A configuração da associação no modelo faz tudo isso para você. Isso faz parte da magia dos trilhos. : D

Agora, é importante observar que, ao usar associações, você precisa garantir que os objetos estejam realmente associados. Em outras palavras, se você tiver 3 objetos de faturamento no seu banco de dados e eles não estiverem associados ao seu objeto host, eles não aparecerão no formulário.

Se você está tentando associar uma cobrança a um host usando uma caixa de seleção, você vai querer adotar uma abordagem diferente, porque seu formulário com apenas faturamento de exibição já associado com seu anfitrião.

Se você está apenas tentando editar ou modificar os faturamentos existentes associados ao host, onde a caixa de seleção representa um atributo 'pago' (um booleano), por exemplo, essa abordagem está bem e seu código de formulário ficaria algo assim:

<% f.fields_for :billings do |b| %><br />
  <%= b.check_box :paid %> <%= b.title %>
<% end %>

Então, talvez esclareça o que você está tentando realizar do ponto de vista da funcionalidade e podemos encontrar uma solução melhor.

Outras dicas

Não tenho certeza sobre minha resposta, mas vou tentar ...

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

Parece-me que é um problema com os loops for ...

No seu código de exemplo, você está percorrendo o @billings (uma matriz de objetos de faturamento passados ​​​​do seu controlador) e chamando o atual billing.

No seu código de formulário, você está percorrendo o :billings (símbolo referenciando os ActiveRecords de faturamento) e chamando o atual obj.Então, de forma confusa, seu código reutiliza o nome da variável obj novamente na função @billings.collect...mas isso deve ter escopo privado local e não afetar seu loop principal, mas é difícil de interpretar à primeira vista.

De qualquer forma, já que o material dentro do seu loop de formulário não faz referência obj, está usando a variável billing--que não muda quando você faz o loop, mas mantém o último valor que tinha:o último item do loop anterior!Isso explica por que você vê apenas a última tag.(Também o debug(@billings) A função faz seu próprio loop através dos registros - ela não está dentro do loop Fields_for do.)

Eu começaria alterando a primeira linha do código do seu formulário para reutilizar o nome da variável billing novamente, assim:

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

Sintaxe de bloco do Ruby pode ser bastante confuso no início - ou, diabos, sempre que você está lendo um código que não escreveu sozinho - mas quando você divide tudo nos componentes básicos, geralmente é apenas um loop por um conjunto de itens e execução de alguns função em cada um.Cuidado também com a confusão entre nomes de aparência semelhante:@billing, @billings, :billings e billings são coisas diferentes de Ruby e Rails.Boa sorte!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top