Virtus: Replace accepts_nested_attributes (one-to-many) with a form object

Since more than a month, I’ve been trying to get around the secrets of form objects in Rails 4.

Using virtus , I can already create very simple forms. However, I cannot create a form object that replaces accepts_nested_attributes_for (in the model) and fields_for (in the form).

To this question I will explain an example of a small phone book: the form makes it possible to enter a person’s name and 3 phone numbers at once (find the entire code here ).

Now I am trying to do the same with a form object. I get to this:

 # forms/person_form_new.rb class PersonFormNew class PhoneFormNew include Virtus include ActiveModel::Model attr_reader :phone attribute :phone_number, String end include Virtus include ActiveModel::Model attr_reader :person attribute :person_name, String attribute :phone, PhoneFormNew def persisted? false end def save if valid? persist true else false end end private def persist @person = Person.create(name: person_name) @person.phones.build(:phone) end end # views/people/new.html.erb <h1>New Person</h1> <%= form_for @person_form, url: people_path do |f| %> <p> <%= f.label :person_name %> </ br> <%= f.text_field :person_name %> </p> <p> <%= f.fields_for :phone do |f_pho| %> <%= f_pho.label :phone_number %> </ br> <%= f_pho.text_field :phone_number %> <% end %> <p> <%= f.submit %> </p> <% end %> 

It gives me an error

undefined method `stringify_keys' for: phone: Symbol

line: @person.phones.build(:phone)

However, I am afraid that this is not the only mistake.

Can you tell me a way to implement a one-to-many assignment with a form object (preferably using Virtus)?

+4
source share
1 answer

One solution is to create a related object in a separate function in the form model. I was calm by doing the following:

  def persist! @user.save! @account.save! create_admin_membership end def create_admin_membership @membership = Membership.create! do |membership| membership.user = @user membership.account = @account membership.admin = true end end 

Here you can find an extended explanation: http://w3facility.org/question/how-to-create-another-object-when-creating-a-devise-user-from-their-registration-form-in-rails/

+1
source

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


All Articles