guides.rubyonrails.org 读书笔记(六)


A Guide to Active Record Associations

 

To learn more about the different types of associations, read the next section of this guide. That’s followed by some tips and tricks for working with associations, and then by a complete reference to the methods and options for associations in Rails.

 

2 The Types of Associations

In Rails, an association is a connection between two Active Record models. Associations are implemented using macro-style calls, so that you can declaratively add features to your models.

For example, by declaring that one model belongs_to another, you instruct Rails to maintain Primary Key–Foreign Key information between instances of the two models, and you also get a number of utility methods added to your model.

2.3 The has_many Association

一对多的关系

A has_many association indicates a one-to-many connection with another model. You’ll often find this association on the “other side” of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model.

 

2.4 The has_many :through Association

多对多的关系,一般通过第三个model,也就是中介model(join models)来实现多多映射。 这其实也是through的含义了。

 

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

一到多,又是一到多,
The has_many :through association is also useful for setting up “shortcuts” through nested has_many associations.
For example, if a document has many sections, and a section has many paragraphs, you may sometimes want to get a simple collection of all paragraphs in the document.

2.5 The has_one :through Association

This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model.

2.6  The has_and_belongs_to_many Association
A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model .(这里提的是model,但并没有说没有第三个表。相反,这里关系表还是必须要有的)

2.7 区别 belongs_to and has_one

 

If you want to set up a 1–1 relationship between two models, you’ll need to add belongs_to to one, and has_one to the other. How do you know which is which?

字面上理解是,belongs_to是关联关系,所属关系;而has_one是包含关系。

The distinction is in where you place the foreign key (it goes on the table for the class declaring the belongs_to association), but you should give some thought to the actual meaning of the data as well. The has_one relationship says that one of something is yours – that is, that something points back to you.

 

2.8 区别 has_many :through and has_and_belongs_to_many

 

这两种都能实现多对多的关系。

(1)Rails offers two different ways to declare a many-to-many relationship between models. The simpler way is to use has_and_belongs_to_many , which allows you to make the association directly.

(2)The second way to declare a many-to-many relationship is to use has_many :through . This makes the association indirectly, through a join model.

 

The simplest rule of thumb is that you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don’t need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship (though you’ll need to remember to create the joining table in the database).

You should use has_many :through if you need validations, callbacks, or extra attributes on the join model.

 

2.9 Polymorphic Associations

 

A slightly more advanced twist on associations is the polymorphic association . With polymorphic associations, a model can belong to more than one other model, on a single association.

You can think of a polymorphic belongs_to declaration as setting up an interface that any other model can use.

这个部分非常有意义~~

 

 

2.10 Self Joins

 

In designing a data model, you will sometimes find a model that should have a relation to itself. For example, you may want to store all employees in a single database model, but be able to trace relationships such as between manager and subordinates. This situation can be modeled with self-joining associations:

class Employee < ActiveRecord::Base
  has_many :subordinates, :class_name => "Employee",
    :foreign_key => "manager_id"
  belongs_to :manager, :class_name => "Employee"
end

 

总结一下:

(1) has_***都是在被关联的(associated)table中创建外键,此外键映射到含有声明model所对应表。

比如下面的例子,外键是在accounts表,映射到suppliers表

class Supplier < ActiveRecord::Base
  has_one :account
end

(2)belongs_**是在声明model对应的table中创建一个外键

比如下面的例子,外键是在orders表,映射到customers表

class Order < ActiveRecord::Base
  belongs_to :customer
end

 

(3)belongs_to和has_many 经常成对出现。以下例而言

 

class Comment < ActiveRecord::Base
  belongs_to :post
end

 

class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
 
  has_many :comments
end

 

belongs_to建立关系:Each comment belongs to one post;

has_many建立关系: One post can have many comments;

数据关系:if you have an instance variable @post containing a post, you can retrieve all the comments belonging to that post as the array @post.comments .

 

 

 

3 Tips, Tricks, and Warnings

3.1  Controlling Caching

 

3.2  Avoiding Name Collisions

You are not free to use just any name for your associations. Because creating an association adds a method with that name to the model, it is a bad idea to give an association a name that is already used for an instance method of ActiveRecord::Base . The association method would override the base method and break things. For instance, attributes or connection are bad names for associations.

 

3.3 Updating the Schema

这个部分是需要手动编码的部分。

Associations are extremely useful, but they are not magic. You are responsible for maintaining your database schema to match your associations. In practice, this means two things, depending on what sort of associations you are creating.

(1) For belongs_to associations you need to create foreign keys, and

(2) for has_and_belongs_to_many associations you need to create the appropriate join table.

 

If you create a has_and_belongs_to_many association, you need to explicitly create the joining table. Unless the name of the join table is explicitly specified by using the :join_table option, Active Record creates the name by using the lexical order of the class names. So a join between customer and order models will give the default join table name of “customers_orders” because “c” outranks “o” in lexical ordering.

 

We pass :id => false to create_table because that table does not represent a model. That’s required for the association to work properly . If you observe any strange behaviour in a has_and_belongs_to_many association like mangled models IDs, or exceptions about conflicting IDs, chances are you forgot that bit.

 

3.4 Controlling Association Scope

 

By default, associations look for objects only within the current module’s scope. This can be important when you declare Active Record models within a module.

To associate a model with a model in a different namespace, you must specify the complete class name in your association declaration:

 

4. Detailed Association Reference

4.1 belongs_to Association Reference

 

The belongs_to association creates a one-to-one match with another model.

If the associated object has already been retrieved from the database for this object, the cached version will be returned. To override this behavior (and force a database read), pass true as the force_reload argument.

 

Cached 提供的作用,在开发或者测试阶段,经常会有很大的问题。

 

 

 

 

 

 

 

 

 

 

 

 

 

4.5  Association Callbacks

 

Association callbacks are similar to normal callbacks, but they are triggered by events in the life cycle of a collection. There are four available association callbacks:

 

 

4.6 Association Extensions

You’re not limited to the functionality that Rails automatically builds into association proxy objects. You can also extend these objects through anonymous modules, adding new finders, creators, or other methods.

 

 

 

 

 

一个典型的关系建立的步骤,

(1)生成一个需要被关联的Model:$ rails generate model Comment commenter:string body:text post:references

这样就得到如下关联模型,

class Comment < ActiveRecord::Base
  belongs_to :post
end

以及db migration文件,此文件包含有关联信息 t.references :post;The t.references line sets up a foreign key column for the association between the two models.

(2)更改数据库,运行命令$ rake db:migrate

(3)You’ll need to edit the post.rb file to add the other side of the association: 添加

class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
 
  has_many :comments
end

(4)为新增加的被关联的model,添加路由信息:Adding a Route for Comments

(5)生成与被关联对象相关的控制器:Generating a Controller:$ rails generate controller Comments

注意,这一步会生成 控制器和视图。

(6)编辑相关的控制器和视图,实现被关联模型 的数据显示和url跳转链接。

 

如果(1)的不是通过reference生成,那相关的外键则需要手动添加。 而对于 has_and_belongs_to_many,又需要手动添加关系表。具体参考3.3。

更简单的说明:

(1)$ rails generate scaffold student given_name:string middle_name:string family_name:string birthday:date grade_point_average:decimal start_date:date

(2)$ rails generate scaffold award award_name:string description:string year:integer student_id:integer

(3)$ rake db:migrate

(4)award.rb & student.rb,添加关系声明belongs_to & has_many

如此看:关系声明是在数据迁移之后的,那关系什么如何作用到数据库层面呢?。这里要注意了,所以model的逻辑本身都不是数据库层面的,比如model中的校验,这个校验是model自身的,是model层面的,而不是数据库这个level的。理解了这点,就能理解关系声明的scope了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值