Ich versuche, das has_many
Muster zu implementieren, das in "Ruby on Rails Nested Attributes" gezeigt wird. Ich kombiniere es mit einigen meiner eigenen Methoden und weiß genau, wo es eine Ausnahme auslöst und warum. Ich weiß einfach nicht, wie ich das beheben soll. Ich verwende accepts_nested_attributes
. Ich habe eine Klasse namens ProfilePhones
.Probleme mit Objektreflexion in verschachtelter Form mit has_many association
In profile_email.rb:
def self.attrs
column_names.map(&:to_sym) - [:created_at, :updated_at]
end
Die Verwendung der oben für verschachtelte Attribute also, wenn sich das Modell ändert es nicht die anderen Controller brechen. Im profiles_controller.rb ich habe:
def profile_params
params.require(:profile).permit(.... profile_phones_attributes: ProfilePhone.attrs)
Im Profilaufrufe Ordner habe ich mit den Feldern für die ProfilePhone Datensätze _profile_email_fields.html.erb:
<%= f.text_field :kind, placeholder: "Type" %>
<%= f.text_field :email_address, placeholder: "Email" %>
Es ist ein bisschen mehr in diesem Teil , aber ich vereinfache es, weil das Teil gut funktioniert. Im Haupt _form Teil habe ich folgendes:
<%= f.fields_for :profile_emails do |f| %>
<%= render 'profile_email_fields', f: f %>
<%= link_to_add_fields('Add Another Email', f, :profile_emails) %>
<% end %>
In application_helper.rb:
def link_to_add_fields(name = nil, f = nil, association = nil, options = nil, html_options = nil, &block)
f, association, options, html_options = name, f, association, options if block_given?
options = {} if options.nil?
html_options = {} if html_options.nil?
if options.include? :locals
locals = options[:locals]
else
locals = { }
end
if options.include? :partial
partial = options[:partial]
else
partial = association.to_s.singularize + '_fields'
end
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, child_index: 'new_record') do |builder|
render(partial, locals.merge!(f: builder))
end
html_options['data-form-prepend'] = raw CGI::escapeHTML(fields)
html_options['href'] = '#'
content_tag(:a, name, html_options, &block)
end
schließlich im profiles.coffee:
$('[data-form-prepend]').click (e) ->
obj = $($(this).attr('data-form-prepend'))
obj.find('input, select, textarea').each ->
$(this).attr 'name', ->
$(this).attr('name').replace 'new_record', (new Date).getTime()
return
obj.insertBefore this
false
Das Problem in der application_helper
ist Methode oben in der folgenden Zeile:
new_object = f.object.class.reflect_on_association(association).klass.new
f.object.class kehrt:
ProfileEmail(id: integer, kind: string, email_address: string, profile_id: integer, created_at: datetime, updated_at: datetime)
Verein ist als :profile_emails
gesetzt. Das Problem ist, dass dies Nil produziert. Außerdem muss ich über das Modell nachdenken, zu dem es gehört. Wenn ich das Gerät, mit:
Profile.reflect_on_association(association).klass.new
Es gibt:
-> #<ProfileEmail id: nil, kind: nil, email_address: nil, profile_id: nil, created_at: nil, updated_at: nil>
das ist, was ich will. Wenn ich jedoch zur Ansicht gehe und auf den Link "Eine weitere E-Mail hinzufügen" klicke, passiert nichts. Dies ist wahrscheinlich ein Problem mit meinem coffeescript oder eine Konsequenz des expliziten Aufrufs von Profile. Ich bin mir nicht sicher.
Meine beiden Probleme sind:
In meinem Reflexionsverfahren sollte ich auf Profile werden reflektiert und nicht Profil E-Mail, aber ich bin nicht sicher, wie es zu beheben. Ich kann eine Zeichenfolge des Profilnamens erhalten, aber das hilft nicht.
Wenn ich Profile explizit in der Hilfsmethode aufruft, passiert nichts.
Thank you so viel zu ändern. Manchmal starrt dich das Problem nur ins Gesicht. – splatoperator