Search code examples
ruby-on-railsentity-relationshipscaffolding

Add variable number of items of one type when creating item of another type


I want to create a form that lets you create an item of type A. In that form, you can add multiple items of type B to be associated to the item of type A that you are creating.

I think I understand how to do this in the models- just have a has_many and belongs to relationship.

I'm not really sure how to do this in the UI. Right, now I have the scaffolding and it only has fields for attributes of the item I'm creating. Is there a way to have it show fields for adding items of types defined in has_many that we see in the model file?

EDIT

ClassA
  has_many :ClassB


ClassB
  belongs_to :ClassA

Solution

  • Let's assume your Item A is a Person and Item B is a Project. So, for what you said, a Person has_many Projects. (I decided to use "real world" resources, instead of Item A and Item B for the clarify of the example).

    Here is how you would define your models associations:

    class Person < ActiveRecord::Base
      has_many :projects
      accepts_nested_attributes_for :projects
    end
    
    class Project < ActiveRecord::Base
      belongs_to :person
    end
    

    Then, the form of your Person would look like this:

    <%= form_for @person do |person_form| %>
      ...
      <%= person_form.fields_for :projects do |project_builder| %>
        # Here goes the fields of the projects
        <%= project_builder.text_field :name %>
      <% end %>
      ...
    <% end %>
    

    The key here is fields_for method, which will let you put into your Person form, form builders for the Projects associated with that Person.

    It is important to know that if you are creating a new Person, there are obviously no Projects associated, and therefore the fields_for part would be empty. You might want to start by just basically doing this in the #new action:

    def new
      @person = Person.new
      5.times { @person.projects.build }
    end
    

    Later, and once you get the feeling you know what's going on, you might want to add some buttons in the front end side that would let you "dynamically" add new Projects.