在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?