ruby-on-railsrubyformsform-foraccepts-nested-attributes

How to use nested forms in Rails if the fields have the same name?


I have two models, Dog and Owner, and I want their names to be the same, and would be redundant if I asked to fill out the fields twice (once for the dog and another time for the owner). I'm wondering if there's a simpler way to update the two databases with one input.

<h1>Create a new Dog:</h1>
<%= form_for(@dog) do |f|%>
  <div>
    <%= f.label :name%>
    <%= f.text_field :name%>
  </div><br>
    
  <div>
    <%= f.label :breed%>
    <%= f.text_field :breed%>
  </div><br>
    
  <div>
    <%= f.label :age%>
    <%= f.text_field :age%>
  </div><br>
    
  <div>
    <h3>create a new owner:</h3>
    <%= f.fields_for :owner, Owner.new do |owner_attributes|%>
        <%= owner_attributes.label :name, "Owner Name:" %>
        <%= owner_attributes.text_field :name %>
    <% end %>
  </div>
    
  <%= f.submit %>
    
<% end %>

Solution

  • First of all, not sure why you want to keep the name of the owner and the dog same.

    However, there can be many ways to achieve what you want:

    1. You can simply omit the owner name from the form.

    So you no longer need: <%= owner_attributes.label :name, "Owner Name:" %> OR you no longer need:

    <div>
        <%= f.label :name%>
        <%= f.text_field :name%>
      </div><br>
    

    And in the Owner/Dog model, you can pass the name of the dog/owner in a callback - maybe after_initialize or before_save or before_validation depending on your validation requirements.

    class Dog
      belongs_to :owner
      before_validation :set_name
    
      private
    
      def set_name
        self.name = owner&.name
      end
    end
    
    1. You can make the owner name as a hidden field instead and can write some javascript to update the hidden field with the dog name before submitting the form or onblur event. I would prefer the first approach since it's simpler and more secure than only JS solution to maintain database consistency