Corey
Corey

Reputation: 48

Retrieving multiple records through has_many association

I am working on a Ruby on Rails 4 application which allows users to check off movies that they have seen. I have a page that shows a list of movies, captured through a Film model. Also, I have a Nomination model that captures each Oscar nomination along with Person and Song models that can also have nominations and belong to a Film.

On the page that lists the movies, I also want to show all of the categories that a film is nominated for. I know that I can simply access all of the film nominations via @film.nominations since I have created this has_many association, but this doesn't capture any person or song nominations that belong to that certain movie.

Is there a way to show all of the nominations for a given movie, regardless of whether the nomination is for a film, person, or song?

Here are the models that I currently have:

class Category < ActiveRecord::Base
  # DB columns: name, display_order

  has_many :nominations
end


class Nomination < ActiveRecord::Base
  # DB columns: category_id, nominee_id, nominee_type

  belongs_to :category
  belongs_to :nominee, polymorphic: true

  validates :category, presence: true
  validates :nominee, presence: true
end


class Film < ActiveRecord::Base
  # DB columns: name, image_url
  has_many :nominations, as: :nominee
  has_many :film_views
  has_many :people
  has_many :songs
end


class Person < ActiveRecord::Base
  # DB columns: name, film_id
  belongs_to :film
  has_many :nominations, as: :nominee
end


class Song < ActiveRecord::Base
  # DB columns: name, film_id
  belongs_to :film
  has_many :nominations, as: :nominee
end

Upvotes: 0

Views: 306

Answers (1)

khaled_gomaa
khaled_gomaa

Reputation: 3422

Since in all cases Nomination of any person or song is in someway related with a movie. it makes sense that Nomination should have a movie id; with this your problem is already solved. NB a main reason for that is because a person should belong to one or more Film.

Anyway If you want to get all nominations given a film you can use this code

def all_nominations
  Nominations.where(nominee_type: 'Person', nominee_id: self.people.map(&:id)).or(nominee_type: 'Song', nominee_id: self.songs.map(&:id)).or(nominee_type: 'Film', nominee_id: self.id)
end

Upvotes: 1

Related Questions