Polymorphism and Forms in Ruby on Rails

I have had a lot of questions lately, but thanks to this amazing community, I am learning a ton.

I got all the help I need with polymorphic associations before, and now I have a question about solving forms with polymorphic models. For example, I have Phoneable and User, so when I create my user registration form, I want to be able to assign several phone numbers to the user (for example, cell, work, home).

class User < ActiveRecord::Base has_many :phones, :as => :phoneable end class Phone < ActiveRecord::Base belongs_to :phoneable, :polymorphic => true end class CreateUsers < ActiveRecord::Migration t.column :name, :string t.references :phoneable, :polymorphic => true end class CreatePhones < ActiveRecord::Migration t.column :area_code, :integer t.column :number, :integer t.column :type, :string t.references :phoneable, :polymorphic => true end 

Now, when I create my form, I am embarrassed. I usually did the following:

 - form_for :user, :html => {:multipart => true} do |form| %fieldset %label{:for => "name"} Name: = form.text_field :name ##now how do I go about adding a phone number? ##typically I'd do this: ##%label{:for => "phone"} Phone: ##= form.text_field :phone 

Using polymorphism, I would just approach in the same way, but use fields_for?

 - user_form.fields_for :phone do |phone| %> %label{for => "area_code"} Area Code: = phone.text_field :area_code %label{for => "number"} Number: = phone.text_field :number 

Is this the right approach in this case?

+3
source share
1 answer

Before moving on, I noticed one problem: you do not need t.references with the has_many association tag. Therefore, you do not need the create_user model. What this does is it creates the phonable_id and phoneable_type , you only need it in the polymorphic model.

You are heading the right way with the fields_for approach. But to get this working, you need to tell the models how to handle these fields. You do this using the class method accepts_nested_attributes_for .

 class User < ActiveRecord::Base has_many :phones, :as => :phoneable accepts_nested_attributes_for :phones end 

and one minor thing, you will need to specify fields_for exact name of the association

 - form_for @user do |user_form| - user_form.fields_for :phones do |phone| 

Instead

 - form_for @user do |user_form| - user_form.fields_for :phone do |phone| 

and make sure you remove your %> erb tag :)

Read more about accepts_nested_attributes_for : http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

Hope this helps!

+7
source

Source: https://habr.com/ru/post/1489152/


All Articles