翻译整理自:http://guides.rubyonrails.org/v3.2.13/association_basics.html

想吐槽一句,http://guides.ruby-china.org/  翻译地太慢了!!!

csdn 复制过来格式都有误啊,改格式改了好几遍了。烦心。。。。

什么时候能支持markdown呢-。-

Rails支持以下6种关联类型:

  • belongs_to
  • has_one
  • has_many
  • has_many :through
  • has_one :through
  • has_and_belongs_to_many
1. belongs_to :在两个model间建立一对一的关系
 
class Order < ActiveRecord::Base
belongs_to :customer
end
意味着每一个order能且只能被赋给一个customer。
2. has_one :同样在两个model间建立一对一的关系,但语义和结果有点区别。
意味着一个model的每个实例含有或拥有另一个model的一个实例。
class Supplier < ActiveRecord::Base
has_one :account
end
个人理解:有点像是和belongs_to相反的关系,一个是属于,一个是拥有。
3. has_many :和另一个模型有着一对多的关系,经常和belongs_to成对出现。
意味着一个模型每个实例有0个或多个另一模型的实例。
class Customer < ActiveRecord::Base
has_many :orders
end
注意: 此处order为复数形式。
4. has_many :through 经常被用来和另一个模型建立多对多的关系。
原model可以通过(through)第三方model和0个或多个另一model的实例进行匹配。
假想一个病人看病的例子,病人需要预约医生才可以看病,关系可被定义为:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients,:through => :appointments
end class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, :through => :appointments
end
5. has_one :through  一对一的关系,与上一个类似,原model可以通过第三方model和1个另一model的实例相匹配。
举例:每个供应商有一个账号,每个账户有一个相关联的账号历史,关系定义如下:
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, :through => :account
end class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end class AccountHistory < ActiveRecord::Base
belongs_to :account
end
6. has_and_belongs_to_many :直接和另一个model建立多对多的关系,不再通过中间model。
例如,每个配件有很多个部分,每个部分出现在很多个配件中,定义如下:
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
end

到底该选用哪一种关系呢???
1. 该选用 has_one 还是 belongs_to ?
区别在于你在哪里放置了foreign key
ps : foreign key(外键):父数据表(Parent Entity)的主键(primary key)会放在另一个数据表,当做属性以创建彼此的关系,而这个属性就是外键。参考:
http://www.w3school.com.cn/sql/sql_foreignkey.asp
如:Orders表中的customer_id就是Orders表的外键,而order_id是主键。
举例说明:Supplier 和 account 的关系
class Supplier < ActiveRecord::Base
has_one :account
end class Account < ActiveRecord::Base
belongs_to :supplier
end
为什么是这样呢?从正常逻辑思维来看,它确实应该如此,另外它的数据迁移文件可能长这样:
class CreateSuppliers < ActiveRecord::Migration
def change
create_table :suppliers do |t|
t.string :name
t.timestamps
end create_table :accounts do |t|
t.integer :supplier_id
t.string :account_number
t.timestamps
end
end
end
一看就知道 supplier_id 是accouts表的外键,所以,关系定义确实是对的。

2. 该选用 has_many :through 还是 has_and_belongs_to_many ?
它们其实是Rails提供的两种声明多对多关系的方法。后者更简单些,它允许你直接定义多对多关系。

例子见上面,如果你需要将关系模型作为一个独立的数据表而且不需要对该关系模型做任何处理的话,使用
has_and_many是比较简单的,尽管你还要在数据库中建立一个连接表(joining table),比如 assemblies_parts表。

但是如果在连接模型中你需要数据验证(validations),回调函数(callbacks),或者其他参数时,你就应该使用has_many :through这种方式了。

3. 多态关联(polymorphic association)
A model can belong to more than one other model, on a single association.
For example, you might have a picture model that belongs to either an employee model or a product model.
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
end class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
end

4. 自我连接(self joins)

有时候你需要一个model,它的内部之间也有联系。
比如你想把所有的雇员都存放在一个单独的数据库模型中,但它同时又能跟踪经理和下属的关系。
可以这样定义:
class Employee < ActiveRecord::Base
has_many :subordinates, :class_name => "Employee",
:foreign_key => "manager_id"
belongs_to :manager, :class_name => "Employee"
end

这样一来,你就可以获取 @employee.subordinates 和 @employee.manager 了。


不想写地太长,所以只摘取了其中部分,另外能力有限,有些部分没能翻译。
今天在大神的点拨下基本完成了数据关系的设计, 嘿嘿, 感谢HalFtaN, 开开心心做国创去咯 ^_^

欢迎各位指正 :)

The Six Types of Rails Association的更多相关文章

  1. pcap文件的文件头的link type

    http://www.tcpdump.org/linktypes.html Link-layer header type values LINKTYPE_ name LINKTYPE_ value C ...

  2. Unable to determine the principal end of an association between the types '***. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

    MVC中数据库表如果是一对一的主键关系时要加[Required]不然会出错Unable to determine the principal end of an association between ...

  3. Linq------错误: Unable to determine the principal end of an association between the types

    [Table("bma_stores")] public class Store { //加上即可 [Required] public virtual Product Produc ...

  4. rails enum用于存储数据

    http://api.rubyonrails.org/classes/ActiveRecord/Enum.html 新的项目中有一个字段是展示类型,可以用下拉框去做,用string存储具体的类型字段. ...

  5. How to Test Controller Concerns in Rails 4

    Concerns are a new feature that was added in Rails 4. They allow to clean up code in your models and ...

  6. Mybatis 高级结果映射 ResultMap Association Collection

    在阅读本文章时,先说几个mybatis中容易混淆的地方: 1. mybatis中的列不是数据库里的列而是查询里的列,可以是别名(如 select user_name as userName,这时col ...

  7. 10 steps to get Ruby on Rails running on Windows with IIS FastCGI- 摘自网络

    Since the original tech preview release of FastCGI last year, we've been seeing a lot of requests fo ...

  8. Nginx + unicorn 运行多个Rails应用程序

    PS:第一次写的很详细,可惜发布失败,然后全没了,这是第二次,表示只贴代码,剩下的自己领悟好了,这就是所谓的一鼓作气再而衰吧,希望没有第三次. 版本: ruby 2.1.0 rails 4.0.2 n ...

  9. Rails Migration Data Model栏位修改及数据类型介绍

    测试版本Ruby:2.3.1   Rails:5.0.1 一.增加栏位       给devise默认的用户新增增加username字段 $ rails generate migration add_ ...

随机推荐

  1. Bootstrap_排版_表格

    一.基础表格 <table class="table"> <thead> <tr> <th>表格标题</th> < ...

  2. 局部视图(partial)

    局部视图(partial) 原文:Partial Views作者:Steve Smith翻译:张海龙(jiechen).刘怡(AlexLEWIS)校对:许登洋(Seay).何镇汐.魏美娟(初见) AS ...

  3. 拦截QT关闭窗口的CloseEvent

    QDialog类下有一个虚函数 void QDialog::closeEvent (  QCloseEvent   *  e   )  [virtual protected] 通过实现closeEve ...

  4. 初级ant的学习

    一.安装ant 到官方主页http://ant.apache.org下载新版(目前为Ant1.8.1)的ant,得到的是一个apache-ant-1.8.1-bin.zip的压缩包.将其解压到你的硬盘 ...

  5. NWERC 2012 Problem I Idol

    又是个2-sat的模板题: 反正评委的选择必须有一个是正确的,1错误,那么2就必须正确: 这就是一个2-sat问题. 直接上白书的模板啊,不过稍微要注意的一点是对于第一个点必须要选择,不然就违反了题意 ...

  6. 如何测试 Android 中的定时事件

    测试定时事件不太容易,比如要测试 AlarmManager 中定时明天4点的一个事件,你总不能等到明天4点再看看吧. Roman Nurik 提供了两个用来测试定时事件的命令:adb shell du ...

  7. Android与服务器端数据交互(http协议整合struts2+android)

    在android中有时候我们不需要用到本机的SQLite数据库提供数据,更多的时候是从网络上获取数据,那么Android怎么从服务器端获取数据呢?有很多种,归纳起来有 一:基于Http协议获取数据方法 ...

  8. Reverse Linked List 递归非递归实现

    单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...

  9. 查看SGA和PGA使用率

    select name,total,round(total-free,2) used, round(free,2) free,round((total-free)/total*100,2) pctus ...

  10. TCP/IP FTP/TFTP

    引言 从一台计算机向另一台计算机传送文件是在连网或互联网环境中最常见的任务.而FTP和TFTP就是这样的协议. 关于文件传输协议FTP? 端口21使用服务TCP [FTP模型] FTP连接? 1.控制 ...