Hi,
I am new to Ruby and Rails programming and am having difficulty with the
following scenario…
Consider the following model:
class Studio < ActiveRecord::Base
has_many :movies
has_and_belongs_to_many :actors
end
class Movie < ActiveRecord::Base
belongs_to :studio
has_and_belongs_to_many :actors
end
class Actor < ActiveRecord::Base
has_and_belongs_to_many :studios
has_and_belongs_to_many :movies
end
The underlying database structure is as follows:
studios
id: integer
movies
id: integer
studio_id: integer
actors
id: integer
actors_studios
actor_id: integer
studio_id: integer
actors_movies
actor_id: integer
movie_id: integer
(Note that in this case I am not using a movies_studios table)
The question I want to answer is, given an actor_id and studio_id, how
do I find all related movies? Or, stated differently, how do I find all
movies for a given studio/actor combination?
I have come up with several possible alternatives, but none of them
really satisfy-- or, at least, I think it should be able to be done
better. My possible choices are:
-
Use straight SQL – disregarded as not the “Ruby Way”
-
Use find_by_sql – ditto (although, perhaps less so)
-
Do the following:
Movie.find_by_studio_id().collect do |movie|
movie.actors.each.do |actor|
if (actor.id == ) then
end
end
endThis is not satisfying because I have to loop through all actors
associated with each movie to see if I have a match. Seems like there
should be a better way… -
Do the following:
studio = Studio.find()
actor = studio.actors.find()
actor.movies.each do |movie|
endThis, again, is less than satisfying-- so many SQL calls…
So, is there a way to accomplish what I am looking for in a way that
generates minimal SQL? For example, if I were just going after the data
using direct SQL I would write the following query:
SELECT * FROM movies m
INNER JOIN actors_movies am ON m.id = am.movie_id
WHERE am.actor_id =
AND m.studio =
Do I need to create a model of actors_movies to do what I am trying to
do (which also is less than satisfying)? Seems like there has to be an
efficient way to get the data I am looking for without resulting in
multiple SQL queries, and without having to “filter” the result set
afterwards.
Thanks for any insights.