在 Ruby on Rails 中正确实现多对多? [英] Correct implementation of many-to-many in Ruby on Rails?

查看:47
本文介绍了在 Ruby on Rails 中正确实现多对多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新手问题,当心!我想在 Rails 中实现一个基本的多对多关系,我试图找出哪种方法被认为是最rails 方式".在传统的非 ActiveRecord DB 中,我刚刚创建了两个表和一个联结表,并编写了一堆逻辑以确保在对其中任何一个表执行操作时都考虑到所有三个表.

Newbie question, beware! I'd like to implement a basic many-to-many relationship in Rails and I'm trying to find out which approach is considered the most "rails way" of them. In a traditional non-ActiveRecord DB I'd just created two tables and a junction table and written a bunch of logic to make sure all three tables are taken in consideration when operations are performed on any of them.

这是我第一次使用 ORM,所以我试图找出 ActiveRecord 是否能以某种方式为您简化流程,也许不需要手动创建联结表.

This is my first time using an ORM and so I'm trying to find out if perhaps ActiveRecord somehow simplifies the process for you, perhaps by not requiring a junction table to be manually created.

Railscasts 似乎是 Rails 智慧的著名来源,这个 cast 中的两种方式是真正的Rails 方式"还是我可以做得更好?- http://railscasts.com/episodes/47-two-many-to-许多

Railscasts seems like a reputable source of Rails wisdom, are the two ways in this cast truly "Rails way" or can I do better? - http://railscasts.com/episodes/47-two-many-to-many

推荐答案

基本上有两种方式:has_and_belongs_to_many (habtm) 和 has_many with指向另一个关联的 :through 选项.两者都需要连接表;后者就是我们所说的连接模型,因为您通常会向连接添加更多信息.

There's basically two ways: has_and_belongs_to_many (habtm) and has_many with a :through option that points to another association. Both require join tables; the latter is what we call a join model, because you typically add more information to the join.

例如,考虑一个带有用户模型的应用程序,该应用程序为站点添加书签.一种方法是将其实现为 habtm 关系

For example, consider an application with a User model who bookmarks Sites. One way would be to implement it as a habtm relationship

class User < ActiveRecord::Base
  has_and_belongs_to_many :sites
end
class Site < ActiveRecord::Base
  has_and_belongs_to_many :users
end

user.sites << Site.find(...)

此建模还需要创建 sites_users 表,该表必然缺少主键.

This modeling will also require creating the sites_users table, which necessarily will lack a primary key.

这样做的问题是您可能希望在其上存储其他信息,因此您最好使用连接模型,在本例中为书签:

The problem with this is you're likely to want to store additional information on it, so you might as well go with a join model, in this case Bookmark:

class User < ActiveRecord::Base
  has_many :bookmarks
  has_many :sites, :through => :bookmarks
end
class Site < ActiveRecord::Base
  has_many :bookmarks
  has_many :users, :through => :bookmarks
  #edit: adding validation for requiring at least one bookmark
  validate_before_create :at_least_one_bookmark
  private
  def at_least_one_bookmark
    errors.add_to_base("requires at least one bookmark") unless bookmarks.count > 0
  end
end
class Bookmark < ActiveRecord::Base
  belongs_to :user
  belongs_to :site
end

user.bookmarks.create(:site => Site.find(...) )

更常见的模式是连接模型方法,因为它的多功能性和更好的建模,尽管 habtms 仍然在某种程度上被使用.它们只是二维的,你真的需要检查你在做什么,并确保没有一些更丰富的行为需要建模.

The more common pattern is the join model approach for its versatility and better modelling, though habtms are still used somewhat. They're just so two-dimensional that you really need to examine what you're doing and make sure there isn't some richer behavior that needs to be modelled as well.

这篇关于在 Ruby on Rails 中正确实现多对多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆