在Rails中创build一个多对多的关系

这是我想要实现的一个简单的例子,我对Rails比较陌生,并且正在努力让自己的头脑模仿模型之间的关系。

我有两个模型, User模型和Category模型。 用户可以与许多类别关联。 一个特定的类别可以出现在许多用户的类别列表中。 如果一个特定的类别被删除,这应该反映在用户的类别列表中。

在这个例子中:

我的Categories表包含五个类别:

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |  ID | 名称|
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |  1 | 体育| 
 |  2 | 新闻|
 |  3 | 娱乐|
 |  4 | 技术|
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我的Users表包含两个用户:

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |  ID | 名称|
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |  1 |  UserA | 
 |  2 |  UserB |
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

用户A可以select体育和技术作为他的类别

用户B可以select新闻,体育和娱乐

体育类别被删除,用户A和用户B类别列表反映删除

我已经玩弄创buildUserCategories表,其中包含类别和用户的ID。 这种工作,我可以查找类别名称,但我不能级联删除工作,整个解决scheme似乎是错误的。

使用我发现的belongs_to和has_many函数的例子似乎讨论映射一对一的关系。 例如,对博客文章发表评论。

  • 您如何使用内置的Railsfunction来表示这种多对多的关系?
  • 在使用Rails的时候,在两个可行的解决scheme之间使用单独的表?

你想要一个has_and_belongs_to_many关系。 指南在描述图表和一切工作方面做得非常好:

http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association

你最终会得到这样的结果:

 # app/models/category.rb class Category < ActiveRecord::Base has_and_belongs_to_many :users end # app/models/user.rb class User < ActiveRecord::Base has_and_belongs_to_many :categories end 

现在你需要为Rails创build一个连接表来使用。 Rails不会自动为你做。 这实际上是一个参考每个分类和用户的表格,并且没有主键。

像这样从CLI生成迁移:

 bin/rails g migration CreateCategoriesUsersJoinTable` 

然后打开并编辑它以匹配:

对于Rails 4.0.2+(包括Rails 5.1):

 def change # This is enough; you don't need to worry about order create_join_table :categories, :users # If you want to add an index for faster querying through this join: create_join_table :categories, :users do |t| t.index :category_id t.index :user_id end end 

Rails <4.0.2:

 def self.up create_table :categories_users, :id => false do |t| t.integer :category_id t.integer :user_id end add_index :categories_users, [:category_id, :user_id] end def self.down drop_table :categories_users end 

有了这个,运行你的迁移,你可以连接类别和用户与你习惯的所有便利的访问者:

 User.categories #=> [<Category @name="Sports">, ...] Category.users #=> [<User @name="UserA">, ...] User.categories.empty?