How should I set up an app with only slight variations between models?
I'm making a forum in Rails with the traditional Topic
has many Posts
setup.
However, the forum revolves around a forum game played by users that are pretty much just glorified Topics where the users play by taking turns posting.
In an effort to prototype my application, I created these models:
Topic has many Posts
Game has many GamePosts
InterestCheck has many InterestCheckPost
How it works:
- Users create an InterestCheck in the Find A Game subforum.
- When they find interested players, they start a Game in the Games subforum.
- And general discussion, news bulletins, and other convention message board use are made into Topics.
The reason I created new models for Games and InterestChecks is because I want to add specific metadata to them. For instance, Games can be tagged with various tags while Topics can't.
But it's obviously really ugly and repetitive because I'm recreating the same Topic has many Posts
scenario for Games and InterestChecks. And it creates some really ugly routes like new_game_game_post_path
.
Question
开发者_如何学GoI've been stuck on how to implement this for a while, now. Topics, Games, and InterestChecks all have the same Topic/Post functionality, but I want to ensure that I can extend and add metadata on Games and InterestChecks which is why STI doesn't seem like the solution unless I'm mistakne.
You should be able to do this with single table inheritance and polymorphic associations.
Single table inheritance, which Rails natively supports, will let you have just one Topics table from which Games and InterestChecks can inherit.
Your Topic models will look like:
class Topic < ActiveRecord::Base
...
end
class Game < Topic
...
end
class InterestCheck < Topic
...
end
Just add a type
column to the Topic table. For example, Game.all
is really just Topic.where(:type => 'game')
.
Polymorphic associations will let all of your Topic models access the same Post table.
Your Post model will look like:
class Post < ActiveRecord::Base
belongs_to :postable, :polymorphic => true
...
end
And you support this in your Topic model with:
class Topic < ActiveRecord::Base
has_many :posts, :as => :postable
end
And you'll need to add the postable_type:string
and postable_id:integer
to your Post table. Or you can accomplish the same with just t.references :postable, :polymorphic => true
in your Post migration and it'll add the columns for you.
I haven't tested this.
精彩评论