Виртуальные атрибуты во вложенных формах не записываются
В моем коде вы увидите, что у меня есть ассоциация моделей has_many => own_to и вложенная форма в представлении новых действий.
Кроме того, я использовал Использование двух отдельных полей для одного и того же параметра в обработчике формы Rails?
Проблема в том, что атрибут "prix" (в модели "Projet") записывается в базу данных, а не атрибут "nom" (в модели "Activite").
Возможно, проблема связана с сильными параметрами, но я думаю, что все хорошо в моем коде... Или, может быть, в коде, который я нашел в другом вопросе Stackru, который я связал.
В моем коде есть французские слова: activite - это активность, projet - проект, nom - имя, prix - цена, очень просто:)
Спасибо за вашу помощь!
app / model / projet.rb:
class Projet < ActiveRecord::Base
has_many :activites
accepts_nested_attributes_for :activites,
reject_if: lambda {|attributes| attributes['nom'].blank?}
end
app / models / activite.rb:
class Activite < ActiveRecord::Base
belongs_to :projet
def acttext=(value)
@acttext = value if value
prepare_act
end
def actselect=(value)
@actselect = value if value
prepare_act
end
def acttext
@acttext || self.nom
end
def actselect
@actselect || self.nom
end
private
def prepare_act
self.nom = acttext if acttext
self.nom = actselect if actselect
end
end
app / controllers / projets_controller.rb:
class ProjetsController < ApplicationController
def new
@projet = Projet.new
@activites_options = Activite.pluck(:nom).uniq
2.times { @projet.activites.new}
end
def create
@projet = Projet.new(projet_params)
if @projet.save
redirect_to @projet
else
render 'new'
end
end
private
def projet_params
params.require(:projet).permit(:prix, activites_attributes: [:id, :nom, :heures, :minutes, :acttext, :actselect])
end
end
app / views / projets / new.html.erb:
<div>
<%= form_for @projet do |f| %>
<%= f.label :prix %><br>
<%= f.text_area :prix %><br>
<ul>
<%= f.fields_for :activites do |activites_form| %>
<li>
<%= activites_form.label :choisissez_un_type_dactivité %>
<%= activites_form.select :actselect, @activites_options, {include_blank: true} %>
<%= activites_form.label :ou_créez_en_un_nouveau %>
<%= activites_form.text_field :acttext %><br>
<%= activites_form.label :heures %>
<%= activites_form.text_field :heures %>
<%= activites_form.label :minutes %>
<%= activites_form.text_field :minutes %>
</li>
<br>
<% end %>
</ul>
<p><%= f.submit "Créer le projet" %></p>
<% end %>
</div>
1 ответ
Для того чтобы виртуальные атрибуты работали, вам также необходимо определить установщик и получатель. Это можно сделать либо явным образом определив методы получения и установки, либо используя attr_accessor
,
Пример использования attr_accessor
:
class Activite < ActiveRecord::Base
attr_accessor :nom
....
end
Пример определения и установщика и получателя вручную:
class Activite < ActiveRecord::Base
....
def nom=(value)
super
end
def nom
@nom
end
end
Для второй проблемы с именами классов из-за того, что они французские, вы также хотели бы указать class_name
вариант на обоих has_many
а также belongs_to
указать ваши не английские имена классов следующим образом:
class Projet < ActiveRecord::Base
has_many :activites, class_name: 'Activite'
end
Точно так же для Activite
модель:
class Activite < ActiveRecord::Base
belongs_to :projet, class_name: 'Projet'
end