views:

66

answers:

3

Still new to Rails.

I'm certain there's a naming convention for what I'm trying to do here.

You've got posts, and then you've got tags (I'm not actually making a blog but this a scenario we're all familiar with).

I'd set up my tags like this:

ruby script/generate scaffold tag name:string

Then I'd create a linking table like this:

ruby script/generate migration x_tag_post tag_id:integer post_id:integer

So then in the models I'd have xTagAsset

belongs_to :tags
belongs_to :posts

And then in Tags and Posts I'd say

has_many :x_tag_posts

Is that the right way to do this? I have a feeling there's something better.

A: 

From a purely database perspective you create a table called PostTag which looks something like this. (This is SQL Server syntax, YMMV.)

CREATE TABLE PostTag
(PostId INT,
TagId INT
CONSTRAINT PK_PostTag PRIMARY KEY (PostId, TagId))
mrdenny
Thanks, I've done this frequently outside of Rails--I'm more interested in how to do it according to the Rails conventions.
rpflo
In addition, if you are using a migration to add the join table make sure you exclude the "id" primary key => "create_table :posts_tags, :id => false do |table|"
askegg
+5  A: 

You need to use the built-in Active Record has_and_belongs_to_many or has_many :through => options

HABTM assumes the existence of a table following some basic conventions and lets you use:

class Tags < ActiveRecord::Base 
  has_and_belongs_to_many :assets 
end 

class Asserts < ActiveRecord::Base 
  has_and_belongs_to_many :tags 
end

Has Many through explicitly declares the joining table:

class Tags < ActiveRecord::Base 
  has_many :assets, :through => "assets_tags"
end 

class Asserts < ActiveRecord::Base 
  has_many :tags, :through => "assets_tags"
end

The guides I have linked to above have more details on the implementation.

Toby Hede
Thank you. I forgot to rename my "assets" to "posts" for the question(woops), so wherever you've got Assets up there it should probably be Posts. Thanks again, this exactly what I was looking for.
rpflo
+1  A: 

I prefer the has many through association like what Toby Hede wrote.

class Post < ActiveRecord::Base 
  has_many :assets  
  has_many :tags, :through => :assets 
end

class Asset < ActiveRecord::Base 
  belongs_to :post  
  belongs_to :tag
end 

class Tag < ActiveRecord::Base 
  has_many :assets
  has_many :posts, :through => :assets
end

Hope that will help :)

William Notowidagdo