- 浏览: 182921 次
- 性别:
- 来自: 北京
最新评论
-
angjunwen:
^[1-9]\d*|0$ 这个能处理小数吗?
ruby on rails 常用正则表达式 -
hot88zh:
Hooopo 写道为什么这么多踩的呢 呃。。还真是,你不说我都 ...
Ruby如何用Oauth与第三方网站互动 -
Hooopo:
为什么这么多踩的呢
Ruby如何用Oauth与第三方网站互动 -
robbinwork:
顶
改良程序的11技巧 -
rogerer:
请问ROR上传大文件,怎么解决内存占用问题:1. lightt ...
查询rails的API
原E文地址:http://blog.hasmanythrough.com/2006/04/20/many-to-many-dance-off
我已注意到使用 Rails 关联在创建多对多关系的两种方式上有些混乱。出现混乱是可以理解的,因为has_many :through 还有些新,写它的文章并不多。
Has_and_belongs_to_many 出现的较早,确定的角色与资料超出了你为什么使用多对多关系的假设。事实上,许多人似乎并没有抓住本质上的区别。
就像我们从观看经典影片所学到的,告诉我们两个预期选择之间的区别最好方式是它们的舞蹈。你得观察每个人的表演。那么我们必须在两者之间选择哪个演员呢?
一、连接表:简单的关联
表:
Ruby代码
create_table "dancers_movies", :id => false do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
end
create_table "dancers_movies", :id => false do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
end
模型:
Ruby代码
class Dancer < ActiveRecord::Base
has_and_belongs_to_many :movies
end
class Movie < ActiveRecord::Base
has_and_belongs_to_many :dancers
end
class Dancer < ActiveRecord::Base
has_and_belongs_to_many :movies
end
class Movie < ActiveRecord::Base
has_and_belongs_to_many :dancers
endhas_and_belongs_to_many 关联的设置很简单。连接表只有被连接模型的外键,没有主键或其它属性。(其它属性使用暂时的 push_with_attributes 来支持,但该特征被废弃了。)此处没有给连接表使用的模型类。
二、连接模型:富关联(Rich Associations)
表:
Ruby代码
create_table "appearances", do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
t.column "character_name", :string
t.column "dance_numbers", :integer
end
create_table "appearances", do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
t.column "character_name", :string
t.column "dance_numbers", :integer
end
模型:
Ruby代码
class Appearance < ActiveRecord::Base
belongs_to :dancer
belongs_to :movie
end
class Dancer < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :movies, :through => :appearances
end
class Movie < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :dancers, :through => :appearances
end
class Appearance < ActiveRecord::Base
belongs_to :dancer
belongs_to :movie
end
class Dancer < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :movies, :through => :appearances
end
class Movie < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :dancers, :through => :appearances
end
has_many :through 关联对这个简单例子来说很容易设定的,但是当使用其它特征如 polymorphism 时要有些技巧。用于连接模型的表有个主键并包含了类似其它模型的属性。
三、Checking out the moves
下面是对两种操作基本特征的比较
关联Association has_and_belongs_to_many has_many :through
AKA habtm关联 through association遍历关联
结构Structure 连接表(Join Table) 连接模型(Join Model)
主键Primary Key no yes
富关联Rich Association no yes
代理集合Proxy Collection yes no
Distinct 选择 yes yes
自引用Self-Referential yes yes
早期加载Eager Loading yes yes
多态性Polymorphism no yes
多向连接N-way Joins no yes
该表格内包含了很多东西,现在我们分别看一下:
(1)、结构:
has_and_belongs_to_many 使用了简单的连接表,表的每一行记录只有两个外键。没有为连接表使用模型类的连接记录从不会被直接访问。
has_many :through 更新连接表为一个完整的模型。它使用一个模型类来表现表内的条目。
(2)、主键:
连接表没有主键。我听说一些人,如从外键对创建一个主键,但 Rails 从不为任何东西使用主键。我不能肯定你为什么要得到创建的主键,虽然它可能依据你数据库给你一些性能上的好处。 (我不是一个 DBA ,所以对于主键不想说得太多。)
连接模型有键,就像其它模型。这意味着你可以直接地访问及管理记录。
(3)富关联:
在 Rails 1.1 以前,你使用 push_with_attributes 来存储额外的属性到你的 habtm 连接表内。这样做会带来很多问题,包括随后不能更新属性。Push_with_attributes 现在不再使用了。如果你希望一个带有额外属性的富关联的话,使用连接模型。
(4)、代理集合:
使用 habtm 的一个好处是,关联是个代理集合。这意味着你可以使用关联的 << 方法在连接表内创建条目,就像 has_many 关联。因为连接模型记录有这些额外属性,所以用同样方式来自动创建连接表条目会更复杂。所以你必须手工创建连接模型条目。(更完整的解释,可参阅我的 Why aren't join models proxy collections? 文章。)
(5)、Distinct 选择:
有时候,连接表(或模型)在同样的记录之间可能有多个引用。例如,一个人可能是一本书的作者及插图绘制者。如果你有多个引用,数据库会返回给你所有与你查询相关多条记录。选项 :uniq 告诉关联过滤重复的对象,以便你只得到每个记录的一条显示。这类似于在 SQL 中使用 DISTINCT 关键字,但这是在 Ruby 内而不是数据库内移除重复发生的记录。这篇文章原只由 habtm 支持的 :uniq 才能查到,但现在通过 through 关联也可以查到。
(6)、自引用:
Habtm 与 through 关联都可是自引用的。Users 的朋友用户就是一个自引用关系的例子。你可以通过在关联上使用带有 :foreign_key 与 :association_foreign_key 选项的 habtm 来完成。同样也可以使用 through 关联,因为它的做法不太明显,所以稍后我会写出如何处理它。
(7)、早期加载
Habtm 与 through 关联都通过 :include 选项来支持被关联对象的早期加载。
(8)、多态性:
连接模型与 through 关联可以用 polymorphic 模型类型工作。
(9)、多向连接
一个 habtm 关联只可以连接两个模型。但有时候你需要表现多个模型的关联。例如登记的可能是一位飞行家,一个乘客,及一个座位的分配。使用 through 关联,你可以创建一个连接模型,它连接你需要的多个模型。技巧部分是如何构建可方便地得到被关联对象的查询。
四、And the winner is...
has_and_belongs_to_many 的使用范围狭小。但 has_many :through 则很广泛。
Seriously, there's no way to pick a winner here. Like any engineering decision, choosing a join table or a join model is a matter of picking the right tool for the job (or the right dancer for the part). Now that you've seen our players go head to head, you can make a better choice about who should get that part.
五、回帖部分:
1、David on 2006年4月21日
关于 distinct 选择 ---- 我认为你可以附加 :select 'DISTINCT *' 给关联,类似于: has_many foos, :through => bars, :select 'DISTINCT *'
我已注意到使用 Rails 关联在创建多对多关系的两种方式上有些混乱。出现混乱是可以理解的,因为has_many :through 还有些新,写它的文章并不多。
Has_and_belongs_to_many 出现的较早,确定的角色与资料超出了你为什么使用多对多关系的假设。事实上,许多人似乎并没有抓住本质上的区别。
就像我们从观看经典影片所学到的,告诉我们两个预期选择之间的区别最好方式是它们的舞蹈。你得观察每个人的表演。那么我们必须在两者之间选择哪个演员呢?
一、连接表:简单的关联
表:
Ruby代码
create_table "dancers_movies", :id => false do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
end
create_table "dancers_movies", :id => false do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
end
模型:
Ruby代码
class Dancer < ActiveRecord::Base
has_and_belongs_to_many :movies
end
class Movie < ActiveRecord::Base
has_and_belongs_to_many :dancers
end
class Dancer < ActiveRecord::Base
has_and_belongs_to_many :movies
end
class Movie < ActiveRecord::Base
has_and_belongs_to_many :dancers
endhas_and_belongs_to_many 关联的设置很简单。连接表只有被连接模型的外键,没有主键或其它属性。(其它属性使用暂时的 push_with_attributes 来支持,但该特征被废弃了。)此处没有给连接表使用的模型类。
二、连接模型:富关联(Rich Associations)
表:
Ruby代码
create_table "appearances", do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
t.column "character_name", :string
t.column "dance_numbers", :integer
end
create_table "appearances", do |t|
t.column "dancer_id", :integer, :null => false
t.column "movie_id", :integer, :null => false
t.column "character_name", :string
t.column "dance_numbers", :integer
end
模型:
Ruby代码
class Appearance < ActiveRecord::Base
belongs_to :dancer
belongs_to :movie
end
class Dancer < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :movies, :through => :appearances
end
class Movie < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :dancers, :through => :appearances
end
class Appearance < ActiveRecord::Base
belongs_to :dancer
belongs_to :movie
end
class Dancer < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :movies, :through => :appearances
end
class Movie < ActiveRecord::Base
has_many :appearances, :dependent => true
has_many :dancers, :through => :appearances
end
has_many :through 关联对这个简单例子来说很容易设定的,但是当使用其它特征如 polymorphism 时要有些技巧。用于连接模型的表有个主键并包含了类似其它模型的属性。
三、Checking out the moves
下面是对两种操作基本特征的比较
关联Association has_and_belongs_to_many has_many :through
AKA habtm关联 through association遍历关联
结构Structure 连接表(Join Table) 连接模型(Join Model)
主键Primary Key no yes
富关联Rich Association no yes
代理集合Proxy Collection yes no
Distinct 选择 yes yes
自引用Self-Referential yes yes
早期加载Eager Loading yes yes
多态性Polymorphism no yes
多向连接N-way Joins no yes
该表格内包含了很多东西,现在我们分别看一下:
(1)、结构:
has_and_belongs_to_many 使用了简单的连接表,表的每一行记录只有两个外键。没有为连接表使用模型类的连接记录从不会被直接访问。
has_many :through 更新连接表为一个完整的模型。它使用一个模型类来表现表内的条目。
(2)、主键:
连接表没有主键。我听说一些人,如从外键对创建一个主键,但 Rails 从不为任何东西使用主键。我不能肯定你为什么要得到创建的主键,虽然它可能依据你数据库给你一些性能上的好处。 (我不是一个 DBA ,所以对于主键不想说得太多。)
连接模型有键,就像其它模型。这意味着你可以直接地访问及管理记录。
(3)富关联:
在 Rails 1.1 以前,你使用 push_with_attributes 来存储额外的属性到你的 habtm 连接表内。这样做会带来很多问题,包括随后不能更新属性。Push_with_attributes 现在不再使用了。如果你希望一个带有额外属性的富关联的话,使用连接模型。
(4)、代理集合:
使用 habtm 的一个好处是,关联是个代理集合。这意味着你可以使用关联的 << 方法在连接表内创建条目,就像 has_many 关联。因为连接模型记录有这些额外属性,所以用同样方式来自动创建连接表条目会更复杂。所以你必须手工创建连接模型条目。(更完整的解释,可参阅我的 Why aren't join models proxy collections? 文章。)
(5)、Distinct 选择:
有时候,连接表(或模型)在同样的记录之间可能有多个引用。例如,一个人可能是一本书的作者及插图绘制者。如果你有多个引用,数据库会返回给你所有与你查询相关多条记录。选项 :uniq 告诉关联过滤重复的对象,以便你只得到每个记录的一条显示。这类似于在 SQL 中使用 DISTINCT 关键字,但这是在 Ruby 内而不是数据库内移除重复发生的记录。这篇文章原只由 habtm 支持的 :uniq 才能查到,但现在通过 through 关联也可以查到。
(6)、自引用:
Habtm 与 through 关联都可是自引用的。Users 的朋友用户就是一个自引用关系的例子。你可以通过在关联上使用带有 :foreign_key 与 :association_foreign_key 选项的 habtm 来完成。同样也可以使用 through 关联,因为它的做法不太明显,所以稍后我会写出如何处理它。
(7)、早期加载
Habtm 与 through 关联都通过 :include 选项来支持被关联对象的早期加载。
(8)、多态性:
连接模型与 through 关联可以用 polymorphic 模型类型工作。
(9)、多向连接
一个 habtm 关联只可以连接两个模型。但有时候你需要表现多个模型的关联。例如登记的可能是一位飞行家,一个乘客,及一个座位的分配。使用 through 关联,你可以创建一个连接模型,它连接你需要的多个模型。技巧部分是如何构建可方便地得到被关联对象的查询。
四、And the winner is...
has_and_belongs_to_many 的使用范围狭小。但 has_many :through 则很广泛。
Seriously, there's no way to pick a winner here. Like any engineering decision, choosing a join table or a join model is a matter of picking the right tool for the job (or the right dancer for the part). Now that you've seen our players go head to head, you can make a better choice about who should get that part.
五、回帖部分:
1、David on 2006年4月21日
关于 distinct 选择 ---- 我认为你可以附加 :select 'DISTINCT *' 给关联,类似于: has_many foos, :through => bars, :select 'DISTINCT *'
发表评论
-
linux下进入rails console提示cannot load such file -- readline
2011-12-17 20:38 2788在linux下输入rails console,之后提示错误,如 ... -
在Windows7中编译Mysql2的GEM
2011-11-08 15:47 0If you still want to force t ... -
CentOS用gem安装Mysql2提示缺少mysql.h
2011-08-30 12:17 2866环境: CentOS6 Ruby1.9.2 Rails3.0. ... -
Rake提示uninitialized constant Rake::DSL解决办法
2011-06-20 00:09 3702环境:Ruby 1.9.1/Rails 3.0.9/Rake ... -
Debian5安装Thin时候出现no such file to load -- openssl
2011-04-19 22:38 1110今天在执行thin install的时候,出现no such ... -
oauth GEM的几个小例子
2011-03-22 08:32 15641、注册并认证你的应用 #!/usr/bin/r ... -
Ruby如何用Oauth与第三方网站互动
2011-03-13 12:25 2076首先是介绍一下这个gem:oauth 项目首页是:http: ... -
升级gem提示缺少no such file to load zlib
2011-02-20 01:16 1343升级gem提示 no such file to load zl ... -
使用Ruby解析图片EXIF数据获取坐标信息
2011-01-10 08:32 1813最近在做一个项目时需要将图片EXIF信息解析出来并获取相应 ... -
Paperclip提示command is not recognized by the 'identify
2011-01-05 00:43 2282用Paperclip来裁减图片,会提示如下错误: /tmp/ ... -
在Debian上部署Ruby On Rails应用(续)
2011-01-05 00:36 1251写在前面: 其实这个续应该和前面那个部署的文章互换一下顺序… ... -
Ruby1.9.2+Rails3.0.3迁移文件中加索引出错的解决办法
2011-01-03 23:53 1546环境: Ruby1.9.2 Rails3.0.3 Gem ... -
rails3使用declarative_authorization注意事项
2010-11-17 17:32 1213Rails3中把declarative_authorizati ... -
rails3使用restful-authentication
2010-11-09 14:01 2011首先要下载支持Rails3的restful-authentic ... -
Ubuntu安装Mysql Gem
2010-11-03 14:49 1302在安装过程中出现如下错误: Building native e ... -
如何寫出有效率的 Ruby Code
2010-09-28 22:44 1020Instance Variables versus Acces ... -
Rails Migration Data Types – MySql – Postgresql – SQLite
2010-06-04 19:09 1209Rails mysql post ... -
request.env
2009-11-11 13:16 1152@client_ip = request.env[" ... -
Active Record Validations and Callbacks
2009-11-08 22:39 2012有许多种在保存数据到 ... -
Ruby on Rails 的检验方法(Validation Helpers)大全
2009-11-06 12:07 1417可以自定义validate(), 这个方法在每次保存数据时都会 ...
相关推荐
has_many:通过 这是关于如何使用has_many :throght创建多对多关联的完整示例has_many :throght在此示例中,我使用staff模型和client模型,其中人员有很多客户,而客户有很多员工 操作说明 在下面的终端中输入 $ ...
通过表多对多 最简单的经验法则是,如果需要将关系模型作为独立实体使用,则应设置has_many :through关系。 示例包括: ... has_many :movies, through: :subscriptions end class Movie < Applicati
入门项目 设置和运行步骤 ...cd project-name bundle install 在database.yml中,将数据库what_ever_you_named_your_start_project的名称更改为project-name rails db:create db:migrate db:seed ...
4. **Associations**:Rails的关联功能允许模型之间建立联系,如`has_many`、`belongs_to`、`has_one`、`has_many :through`等,它们简化了多表操作。 5. **Count、Sum、Average等聚合函数**:Rails提供了计算记录...
偏好 has_many :through 胜于 has_and_belongs_to_many。 使用 has_many :through 允许在 join 模型有附加的属性及验证 # 使用 has_and_belongs_to_many class User < ActiveRecord::Base has_and_...
has_many :through has_and_belongs_to_many 一个简单的DSL,用于配置要复制的字段。 DSL可以应用于您的Rails模型或即时使用。 支持STI(单表继承)子代继承其父变形虫设置。 多种配置样式,例如包含,排除和不
您的模型必须: •包括至少一个has_many,至少一个belongs_to和至少两个has_many:through关系•包括用has_many:through关联实现的多对多关系。 联接表必须包含一个用户可提交的属性-也就是说,该应用程序的用户...
has_many :unread_messages, through: :read_marks, source: :readable, source_type: 'Message' end ``` 现在,当用户查看一条消息时,我们可以调用`read`方法标记消息为已读: ```ruby current_user.read(@...
下一步是在这三个模型之间建立一个has_many :through关系,以便我们可以跟踪谁在开车谁。 它将像这样工作: Taxi -< Rides>- Passengers 这样,出租车可以有很多乘客,而乘客可以有很多出租车! 每个表只有一个...
例如,`has_many :through` 关联可能需要额外配置来处理软删除。 在 Rubysherpas-paranoia-e1f7f33 这个版本中,可能包含了 Paranoia 的源代码和相关文档,你可以通过查看源码来了解其内部实现和可能的自定义选项。...
6. **ActiveRecord associations**:定义模型之间的关系,如属主-从(has_many/belongs_to)、一对一(has_one/belongs_to)和多对多(has_and_belongs_to_many或has_many :through)。 7. **AJAX**:Rails支持无...
3. **模型中启用分页**:在需要分页的模型中,使用`has_many :through`或`has_and_belongs_to_many`关联时,需要在关联上添加`:finder_sql`选项,以便`will_paginate`可以正确处理分页。 4. **控制器中设置分页参数...
2. 在模型(model)中,使用 `has_many :through` 或其他关联方法查询数据,然后调用 `.paginate` 方法。 3. 在视图(view)中,使用 `will_paginate @items` 生成分页链接。 4. 在控制器(controller)中,接收页码...
many_to_many :posts, MyApp.Post, join_through: MyApp.UserPost end defmodule MyApp.Post do ... many_to_many :users, MyApp.User, join_through: MyApp.UserPost end ``` 5. **变更集**:Ecto的变更集...
has_many :books , through : :categories end // Store ( id : integer , address : string ) class Category < ActiveRecord :: Base belongs_to :store has_many :books end // Category ( id : integer , ...
对我们来说幸运的是has_many, through Active Record和has_many, through来显示这种类型的数据的界面也很容易。 课 has_many,通过 假设您正在制作博客,并希望使用户能够注册并评论您的帖子。 帖子和评论之间有...
特征 楷模用户,角色,移动,舞台用户has_many:字符字符belongs_to :用户字符has_many :动作字符has_many :stages, through: ::moves 阶段has_and_belongs_to_many :移动阶段has_many :characters, ...
信使 用于将 JSON 资源同步到核心数据的 Rubymotion 包装器。 -- ###Setup Gemfile gem 'afmotion' ... bundle exec rake pod:... has_many :players , through : [ :teams , :players ] attr_accessor :unpersis
马球 Polo遍历您的数据库并创建示例快照,因此您可以在任何环境中使用真实数据。 Polo接受一个ActiveRecord::Base种子对象,并遍历所有列入白名单的ActiveRecord::... has_many :ingredients , through : :rec