Search code examples
ruby-on-railsruby-on-rails-5nested-forms

Multiple nested forms in rails 5


I'm looking into nested attributes and I have a few questions about relationships between models.

Say I have a Show that has_many Seasons. Both Show and Season can have many Actors and Staff. See table example:

enter image description here

When a Show is created, Season accepts the Show association and both Actors and Staff accept both the Show and Season attributes. Would this be a triple nested form?

So my models would look like this?

class Show < ApplicationRecord
  has_many :seasons, dependent: :destroy
  has_many :actors, dependent: :destroy
  has_many :staff, dependent: :destroy

  accepts_nested_attributes_for :seasons, allow_destroy: true
  accepts_nested_attributes_for :actors, allow_destroy: true
  accepts_nested_attributes_for :staff, allow_destroy: true
end

class Season < ApplicationRecord
  belongs_to :show
  has_many :actors, dependent: :destroy
  has_many :staffs, dependent: :destroy

  accepts_nested_attributes_for :actors, allow_destroy: true
  accepts_nested_attributes_for :staff, allow_destroy: true
end

class Actor < ApplicationRecord
  belongs_to :show
  belongs_to :season
end

class Staff < ApplicationRecord
  belongs_to :show
  belongs_to :season
end

And my Show Controller would look like:

class ShowsController < ApplicationController
  def create
   @show.seasons.build
   @show.seasons.build.actors.build
   @show.seasons.build.staffs.build
  end
end

Solution

  • Correct schema is:

    class Show < ApplicationRecord
      has_many :seasons, dependent: :destroy
      has_many :actors, dependent: :destroy
      has_many :staff, dependent: :destroy
    
      accepts_nested_attributes_for :seasons, allow_destroy: true
      accepts_nested_attributes_for :actors, allow_destroy: true
      accepts_nested_attributes_for :staff, allow_destroy: true
    end
    
    class Season < ApplicationRecord
      belongs_to :show
    end
    
    class Actor < ApplicationRecord
      belongs_to :show
      belongs_to :season
    end
    
    class Staff < ApplicationRecord
      belongs_to :show
      belongs_to :season
    end
    

    The rule is simple - if table objects has a foreign key subject_id, which links it to table subjects, then model Object may contain belongs_to :subject association.

    There is a nice explanation about which relationship to use in your model depending on foreign_key placement.

    Off-topic:

    I don't know the specifics of your project, but it looks a bit offensive. You create new actors and staff each time a new show is created like they are expendable. I do not want to seem cynical, but the actors and the staff can be reused. If so, it could be reasonable to create has_and_belongs_to_many relationships.