Rails: form complessi?

salve a tutt,

sto provando a modificare l’esempio visibile su:

sintesi: un unico form di creazione di un modello A (nell’esempio:
project) che ha molti modelli B (nell’esempio: tasks), gestito con la
minore quantità di codice possibile.

nel mio caso, semplicemente, il modello B ha non un attributo, ma due.

nel controller, il metodo new:
def new
@attachment = Attachment.new
2.times { @attachment.amounts.build }
end

questo è quello che scrivo nel template:

  • form_for :attachment, @attachment, :url => {:action => :create},
    :html => {:multipart => true} do |f|
    .field
    = f.label :title.l, {}, {:class => “required”}
    %br
    = f.text_field :title
  • for amount in @attachment.amounts
    • fields_for “attachment[amounts_attributes][]”, amount do |af|
      .field
      = af.label :tax_base, :tax_base.l
      %br
      = af.text_field :tax_base
      .field
      = af.label :vat_rate, :vat_rate.l
      %br
      = af.text_field :vat_rate, :size => 2

(traduco per chi non usa haml (ma davvero? ma che aspettate?)):

<%- form_for :attachment, @attachment, :url => {:action => :create,
:controller => :attachment}, :html => {:multipart => true} do |f| -%>

<%= f.label :title.l, {}, {:class => "required"} -%>
<%= f.text_field :title -%>
... <%- for amount in @attachment.amounts -%> <%- fields_for "attachment[amounts_attributes][]", amount do |af| -%>
<%= af.label :tax_base, :tax_base.l -%>
<%= af.text_field :tax_base -%>
<%= af.label :vat_rate, :vat_rate.l -%>
<%= af.text_field :vat_rate, :size => 2 -%>
<%- end -%> <%- end -%> ... <%- end -%>

il problema è che il controller riceve, in params:

{“attachment”=>{
“title”=>“”,
“amounts_attributes”=>[
{“tax_base”=>“”},
{“vat_rate”=>“”, “tax_base”=>“”},
{“vat_rate”=>“”}]}
}
invece, vorrei che ricevesse:

"amounts_attributes"=>[{"tax_base"=>"", "vat_rate"=>""},
                       {"vat_rate"=>"", "tax_base"=>""}]}

N.B.: ho provato con IE7, Firefox 3, Safari for Windows, Chrome.

cosa mi sfugge, esattamente?

grazie

pietro

{"attachment"=>{

Toglierei dalle cause il browser, in quanto non centra molto, ma mi
sembra
un comportamento molto strano. Andrei a vedermi l’HTML generato per
capire
in che modo viene strutturato l’HTML.
Ad ogni modo creda che la soluzione migliore sia quella di usare mass
assigmenthttp://ryandaigle.com/articles/2008/7/19/what-s-new-in-edge-rails-nested-models,
che permettono l’inserimento di ‘modelli relazionati’ in modo più
automatico.

Ecco come cambierebbe il tuo codice in linea di massima (non testato)

Questa è la vista.

<% form_for :attachment … do |att| %>
<%= att.text_field :title %>
<% att.fields_for :amounts do |amt| %>
<%= amt.text_field :tax_base %>
<%= amt.text_field :vat_rate %>
<% end %>
<% end %>

che dovrebbe ritornare

{
:title => ‘title’,
:amounts => [
{ :tax_base => ‘tax_1’, vat_rate => ‘vat_1’ },
{ :tax_base => ‘tax_2’, vat_rate => ‘vat_2’ }
]
}

Nel model aggiungi la proprietà accessible a true, così riesci a definire
l’inserimento degli amounts in automatico. In altre parole se trova
nell’ash
di ritorno una entry :amounts, per ogni elemento presente nell’arrai
genera
un record associato ad attachment.

class Attachment < ActiveRecord::Base
has_many :amounts, :accessible => true
end

Nell’azione del controller ti basta definire questa singola linea e
tutto
viene creato (attachment ed amounts)

Attachment.create(params[:attachment])

Fammi sapere come va :wink:

On Fri, Sep 19, 2008 at 6:26 PM, Andrea R.
[email protected] wrote:

[…]
Nel model aggiungi la proprietà accessible a true, così riesci a definire
l’inserimento degli amounts in automatico. In altre parole se trova nell’ash
di ritorno una entry :amounts, per ogni elemento presente nell’arrai genera
un record associato ad attachment.

class Attachment < ActiveRecord::Base
has_many :amounts, :accessible => true
end

da quel che ho capito, questa feature era presente solo in edge, però
è stata tolta pochi giorni fa, e quindi non
c’è più…
tu usi edge?

On Mon, Sep 22, 2008 at 12:13 PM, Pietro G.
[email protected]wrote:

class Attachment < ActiveRecord::Base
has_many :amounts, :accessible => true
end

da quel che ho capito, questa feature era presente solo in edge, però
è stata tolta pochi giorni fa, e quindi non c’è più…

tu usi edge?

Che pacco… no, non lo uso, ma mi ricordavo di questa feature dopo
averla
letta, e credevo fosse bella che inserita ormai.


Andrea R., http://mikamai.com
Writing http://sensejs.wordpress.com/
Collaborating http://therubymine.it
Reading http://stacktrace.it