Here's the scoop:
As a learning exercise, I'm trying to write a Rails clone of one of the many location-based games out there (Foursquare, Gowalla, etc.) I have Users who create and check in to Stores.
In ActiveRecord terms:
:user has_many :stores
:store belongs_to :user
But now I've created a third model - Checkins. The table behind the model contains two fields, user_id (to record which User made the checkin), and store_id (to record what Store that User checked in to).
Once again, in AR terms:
:checkin belongs_to :user
:checkin belongs_to :store
:user has_many :checkins
:store has_many :checkins
This all works well and good - in my User and Store views, I can call @user.checkins and @store.checkins respectively. The only thing is, in this manner I can only retrieve the user_id or store_id, where I really want to get the username or store name. So I figure the intermediate checkin table lends itself perfectly to a usage of :through:
:user has_many :stores, :through => :checkins
:store has_many :users, :through => :checkins
It makes sense, but the thing is that a User already has_many Stores - the ones he's created! A开发者_C百科nd on his user page, I need to list both the Stores he's created AND the ones he's checked in to. I'm still trying to wrap my head around has_many_and_belongs_to so I'm not sure if that would set me in the right direction. Anyone care to offer a clue?
Rails makes it easy to handle this situation. One solution: your user can use a different relationship name for the second set of stores. For example:
class Checkin
belongs_to :store
belongs_to :user
end
class Store
belongs_to :user
has_many :checkins
end
class User
has_many :stores
has_many :checkins
has_many :visited_stores, :through => :checkins, :source => :store
end
Using the :source
option tells ActiveRecord to look for the Checkin
association :store
when building the list of visited stores. Alternatively, you could've said
has_many :created_stores, :class_name => "Store"
has_many :stores, :through => :checkins
In this case, you're renaming the owned stores instead of the visited ones.
精彩评论