如何在Rails中创建和使用联结表?

时间:2010-03-21 05:26:53

标签: ruby-on-rails

我有以下数据:

  1. 名为Hello的帖子包含类别greet
  2. 另一个名为Hola的帖子包含类别greet, international
  3. 我的架构是:

    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
    

    阅读Rails指南后,上述最合适的关系似乎是:

    class Post < ActiveRecord::Base
      has_and_belongs_to_many :categories
    end
    
    class Category < ActiveRecord::Base
      has_and_belongs_to_many :posts
    end
    

    我的联结表似乎也有主键。我想我需要摆脱它。

    1. 在Rails中生成联结表的初始迁移命令是什么?
    2. 什么是最佳行动方案,我应该放弃posts_categories并重新创建它,还是只删除主键列?
    3. 联结表是否有相应的型号?我使用scaffold来生成联结表代码,我应该删除额外的代码吗?
    4. 假设以上所有内容都已修复且工作正常,我如何查询所有帖子并在视图中显示它们及其命名类别。例如:

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

1 个答案:

答案 0 :(得分:3)

您可能希望从rails API文档中查看this web page

  1. 生成联结表的最简单方法是"script/generate model categories_posts category_id:integer post_id:integer"。请注意,类名应按字母顺序排列。我对整个主要关键事情相当无动于衷,但如果它成为一个问题,你可以生成一个像'script / generate DropPostsCategoriesIdFromPostsCategories posts_categories_id:integer'那样的迁移(确保这个迁移文件做你想要的,我没有'测试它以及它的功能可能因您的导轨版本而异,然后执行rake db:migrate。更改数据库。

  2. 对于您正在使用的班级名称,您可以使用:

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

    has_many through允许您指定连接/联结表的名称。或者你可以放下桌子并用正确的名字重新生成它。

    1. (应该是#3)是的,只是为连接类生成一个模型,不要做整个脚手架。 (见上文)
    2. 查找所有帖子,执行@posts = Post.find(:all)

      之类的操作

      打印出类别,执行类似

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

      在实际的rails代码中,你想在视图中这样做,这更像是一个控制台输出类型的东西。