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 D. 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 W.