I’d like to do something like this:
Category
--------
- id
- name
Tag
--------
- id
- tag
Campaign
--------
- id
- name
- target (either a tag *or* a category)
Is a polymorphic association the answer here? I can’t seem to figure out how to use it with has_one :target, :as => :targetable.
Basically, I want Campaign.target to be set to a Tag or a Category (or potentially another model in the future).
I don’t believe you’re in need of a
has_oneassociation here, thebelongs_toshould be what you’re looking for.In this case, you’d want a
target_idandtarget_typecolumn on your Campaign table, you can create these in a rake with at.references :targetcall (wheretis thetablevariable).Now campaign can be associated to either a
TagorCategoryand@campaign.targetwould return the appropriate one.The
has_oneassociation would be used if you have a foreign key on the target table pointing back to yourCampaign.For example, your tables would have
Tag: id, tag, campaign_idCategory: id, category, campaign_idand would have a
belongs_to :campaignassociation on both of them. In this case, you’d have to usehas_one :tagandhas_one :category, but you couldn’t use a generictargetat this point.Does that make more sense?
EDIT
Since
target_idandtarget_typeare effectively foreign keys to another table, yourCampaignbelongs to one of them. I can see your confusion with the wording because logically theCampaignis the container. I guess you can think of it asCampaignhas a single target, and that’s aTagor aContainer, therefore it belongs in aTagorContainer.The
has_oneis the way of saying the relationship is defined on the target class. For example, aTagwould have be associated to the campaign through ahas_onerelationship since there’s nothing on the tag class that identifies the association. In this case, you’d haveand likewise for a
Category. Here, the:askeyword is telling rails which association relates back to thisTag. Rails doesn’t know how to figure this out upfront because there’s no association with the nametagon theCampaign.The other two options that may provide further confusion are the
sourceandsource_typeoptions. These are only used in:throughrelationships, where you’re actually joining the associationthroughanother table. The docs probably describe it better, but thesourcedefines the association name, andsource_typeis used where that association is polymorphic. They only need to be used when the target association (on the:throughclass) has a name that isn’t obvious — like the case above withtarget andTag — and we need to tell rails which one to use.