Hello all,
I'm currently designing a web app in Rails that lets me keep a directory of free/opensource computer games. Each game has attributes like name, website, review, etc., but each game can also be associated with a set of genres and gameplay elements. The main three tables I'm working with are "games", "genres", "elements", "game_genres", and "game_elements" (the last two being join tables, obviously). The models look like
class Game < ActiveRecord::Base has_many :game_genres has_many :genres, :through => :game_genres has_many :game_elements has_many :elements, :through => :game_elements end class Genre < ActiveRecord::Base has_many :game_genres has_many :games, :through => :game_genres end class Element < ActiveRecord::Base has_many :game_elements has_many :games, :through => :game_elements end class GameGenre belongs_to :game belongs_to :genre end class GameElement belongs_to :game belongs_to :element end
So I've got those associations down pat (although, yes, I realize I probably could have used habtm). Here comes the hard part. As well as joining multiple genres and multiple elements to multiple games, I'd also like to be able to join one genre to multiple genres, one element to multiple elements, and multiple genres to multiple elements. Visually speaking, instead of being able to do just this:
element - game ----- genre element -. .´ game \ / genre element X--- game X genre element / `-- game / `- genre element / game - genre
I'd like to be able to do this:
.-----------------------------------. /'- element - game ----- genre -' / .- element -. .´ game \ / genre ---. \ '- element X--- game X genre ---| `-- element / `-- game / `- genre -. | .- element / game ´ genre -|-' '-----------------------------------'
My first idea was to create three extra join tables, "genre_genres", "element_elements", and "genre_elements". I realized, however, that I could collapse that into one "connections" table:
id :integer a_id :integer b_id :integer a_class_name :string b_class_name :string
The _id's can hold either/both the id of a genre or an element; likewise the _class_name's can hold either/both "genre" or "element".
However, that would require hacking together a custom ActiveRecord class that created relations given a table in the format I described, and I thought, surely there's already something out there that does this?
Then I realized that my unified join table vaguely resembled something I remembered reading about in the Agile Web Development using Rails book I picked up not too long ago: polymorphic associations. Intrigued, I looked around on the web for a while and found a plugin "has_many_polymorphs". I'm not sure if this is what I should use though.
Could someone give me some pointers on how to pull this trick off? Thanks in advance.
-- Elliot Winkler