icantbecool
icantbecool

Reputation: 492

Best way to associate these models?

I have four models, Movies, Person, Cast, and Crew and I'm uncertain on what is best way to associate them all together. Should I use a has many through association or stick with the associations below? Any recommendations would be greatly appreciated.

I want to be able to visit a movie object's show page then be able to list the appropriate cast and crew associated with the movie. In addition, when I visit a Person's show page, I want to list of all their cast roles movies, in addition if they were part of the crew.

class Movie < ActiveRecord::Base
  has_many :cast
  has_many :crew
end

class Person < ActiveRecord::Base
  has_many :cast
  has_many :crew
end

class Cast < ActiveRecord::Base
  belongs_to :movie
  belongs_to :person
end

class Crew < ActiveRecord::Base
  belongs_to :movie
  belongs_to :person
end

Upvotes: 0

Views: 56

Answers (1)

zetetic
zetetic

Reputation: 47548

class Movie < ActiveRecord::Base
  has_many :cast_memberships
  has_many :crew_memberships
  has_many :cast_members, :through => :cast_memberships, :source => :person
  has_many :crew_members, :through => :crew_memberships, :source => :person

  alias_method :cast, :cast_members
  alias_method :crew, :crew_members
end

class CastMembership < ActiveRecord::Base
  belongs_to :movie
  belongs_to :person
end

class CrewMembership < ActiveRecord::Base
  belongs_to :movie
  belongs_to :person
end

class Person < ActiveRecord::Base
end

class CastMember < Person
  has_many :cast_memberships, :foreign_key => :person_id
  has_many :roles, :through => :cast_memberships, :source => :movie
end

class CrewMember < Person
  has_many :crew_memberships, :foreign_key => :person_id
  has_many :jobs, :through => :crew_memberships, :source => :movie
end

> movie = Movie.create! name:"Star Wars"
> cast_member = CastMember.create! name:"Harrison Ford"
> movie.cast << cast_member
> movie.cast # [{name: "Harrison Ford"}]
> cast_member.roles # [{name: "Star Wars"}]

This isn't quite what you need--cast_member.roles should return the characters (["Han Solo"]) not the movies. You could add attributes to the cast_memberships and crew_memberships tables for character data or job descriptions.

Upvotes: 2

Related Questions