I Наконец-то получил это для работы с Rails 4.x.Это основано на ответе Дмитрия / ScotterC, поэтому +1 к ним.
ШАГ 1. Для начала, вот полная модель с полиморфной ассоциацией:
# app/models/polymorph.rb
class Polymorph < ActiveRecord::Base
belongs_to :associable, polymorphic: true
accepts_nested_attributes_for :associable
def build_associable(params)
self.associable = associable_type.constantize.new(params)
end
end
# For the sake of example:
# app/models/chicken.rb
class Chicken < ActiveRecord::Base
has_many: :polymorphs, as: :associable
end
Да, в этом нет ничего нового.Однако вы можете задаться вопросом, откуда берется polymorph_type
и как устанавливается его значение?Это часть базовой записи базы данных, так как полиморфные ассоциации добавляют столбцы <association_name>_id
и <association_name>_type
в таблицу.В действии, когда build_associable
выполняется, значение _type
равно nil
.
ШАГ 2. Передайте и примите дочерний тип
Пусть ваше представление формы отправит child_type
вместе с типичными данными формы, и ваш контроллер должен разрешить его при строгой проверке параметров.
# app/views/polymorph/_form.html.erb
<%= form_for(@polymorph) do |form| %>
# Pass in the child_type - This one has been turned into a chicken!
<%= form.hidden_field(:polymorph_type, value: 'Chicken' %>
...
# Form values for Chicken
<%= form.fields_for(:chicken) do |chicken_form| %>
<%= chicken_form.text_field(:hunger_level) %>
<%= chicken_form.text_field(:poop_level) %>
...etc...
<% end %>
<% end %>
# app/controllers/polymorph_controllers.erb
...
private
def polymorph_params
params.require(:polymorph).permit(:id, :polymorph_id, :polymorph_type)
end
Конечно, ваши представления должны будут обрабатыватьразличные типы моделей, которые «ассоциируются», но это демонстрирует один.
Надеюсь, это поможет кому-то там.(В любом случае, зачем вам полиморфные цыплята?)