开发者

How do I create and use a junction table in Rails?

I have the following data:

  1. A post called Hello has categories greet
  2. Another post called Hola has categories greet, international

My schema is:

create_table "posts", :force => true do |t|
  t.string "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "categories", :force => true do |t|
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "posts_categories", :force => true do |t|
  t.integer  "post_id"
  t.integer  "category_id"
  t.datetime "created_at"
  t.datetime "updated_开发者_开发技巧at"
end

After reading the Rails guide, the most suitable relationship for the above seems to be:

class Post < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

class Category < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

My junction table also seems to have a primary key. I think I need to get rid of it.

  1. What's the initial migration command to generate a junction table in Rails?
  2. What's the best course of action, should I drop posts_categories and re-create it or just drop the primary key column?
  3. Does the junction table have a corresponding model? I have used scaffold to generate the junction table code, should I get rid of the extra code?

Assuming all the above has been fixed and is working properly, how do I query all posts and display them along with their named categories in the view. For example:

Post #1 - hello, categories: greet
Post #2 - hola, categories: greet, international


you might want to check out this web page from the rails API doc.

  1. the easiest way to generate a junction table is "script/generate model categories_posts category_id:integer post_id:integer". Note that the class names should be in alphabetical order. I'm fairly indifferent to the whole primary key thing, but if it becomes an issue, you can generate a migration to drop like 'script/generate DropPostsCategoriesIdFromPostsCategories posts_categories_id:integer' (make sure this migration file does what you want, i haven't tested it and what it does may vary by your version of rails) and then do rake db:migrate. to change the DB.

  2. for the class name you're using, you could use:

class Post < ActiveRecord::Base
   has_many :categories, :through => :posts_categories
end

has_many through lets you specify the names of the join/junction table. or you could drop the table and regenerate it with the right name.

  1. (should be #3) yeah, just generate a model for a join class, don't do the entire scaffold. (see above)

to find all posts, do something like @posts = Post.find(:all)

to print out the categories, do something like

@posts.each do | post |
   print post.name, "\n"
   @posts.categories.each do | cat |
        print "\t", cat.name, "\n"
   end
end

in actual rails code, you'd want to do that in the view, this is more of a console output-type thing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜