高级ActiveRecord:增强你的模型
立即解锁
发布时间: 2025-08-20 01:20:59 阅读量: 1 订阅数: 3 


Rails 3入门:从零开始构建Web应用
### 高级 Active Record:增强你的模型
在数据库操作中,表与表之间的关联是非常重要的一部分。Active Record 为我们提供了强大的功能,让我们可以轻松地处理这些关联关系。本文将详细介绍如何使用 Active Record 来创建和管理不同类型的关联。
#### 声明关联
当一个表需要引用另一个表时,要在引用表中创建外键列。在数据库表中定义好关系后,我们可以使用模型中的一组类似宏的类方法来创建关联,主要有以下几种:
- `has_one`
- `has_many`
- `belongs_to`
- `has_and_belongs_to_many`
例如,`Message` 模型与 `Attachment` 模型之间的关联:
```ruby
class Message < ActiveRecord::Base
has_many :attachments
end
class Attachment < ActiveRecord::Base
belongs_to :message
end
```
Active Record 期望在 `attachments` 表中找到一个名为 `message_id` 的字段(外键引用)。通过这个关联,我们可以使用 `Message.first.attachments` 获取第一个 `Message` 关联的 `Attachment` 对象数组,也可以使用 `Attachment.first.message` 访问第一个 `Attachment` 所属的 `Message`。
#### 创建一对一关联
一对一关联描述的是一个表中的一行与另一个表中的一行精确关联的模式。以博客应用为例,每个用户都有一个对应的个人资料。
##### 添加用户和个人资料模型
首先,我们使用生成器创建 `User` 模型:
```bash
$ rails generate model User email:string password:string
```
对应的迁移文件 `db/migrations/20100306205458_create_users.rb` 如下:
```ruby
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :email
t.string :password
t.timestamps
end
end
def self.down
drop_table :users
end
end
```
`User` 模型只包含用户认证所需的信息。为了存储用户的更多个人信息,我们创建 `Profile` 模型:
```bash
$ rails generate model Profile user_id:integer name:string birthday:date bio:text color:string twitter:string
```
运行迁移任务创建新表:
```bash
$ rake db:migrate
```
##### 声明一对一关联
在 `User` 模型和 `Profile` 模型中声明一对一关联:
```ruby
# app/models/user.rb
class User < ActiveRecord::Base
has_one :profile
end
# app/models/profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
end
```
`User` 模型的 `has_one :profile` 声明表示可以在 `profiles` 表中找到一个 `user_id` 与 `users` 表中某一行主键匹配的记录。`Profile` 模型的 `belongs_to :user` 声明表示每个 `Profile` 对象引用一个特定的 `User`。
##### 测试一对一关联
在控制台中测试关联:
```ruby
>> reload!
Reloading...
>> user = User.create(:email => '[email protected]', :password => 'secret')
>> profile = Profile.create(:name => 'John Doe', :bio => 'Ruby developer trying to learn Rails')
>> user.profile # 返回 nil,因为还未关联
>> user.profile = profile
>> user.save
>> user.profile # 返回关联的 Profile 对象
```
我们还可以使用 `create_profile` 方法一次性创建并保存关联的 `Profile` 对象:
```ruby
>> user.create_profile :name => 'Jane Doe', :color => 'pink'
```
当声明 `has_one` 关联时,Active Record 会自动添加一些方法,方便我们处理关联,如下表所示:
| 方法 | 描述 |
| --- | --- |
| `user.profile` | 返回关联的 `Profile` 对象;若未找到则返回 `nil` |
| `user.profile=(profile)` | 分配关联的 `Profile` 对象,提取主键并将其设置为外
0
0
复制全文
相关推荐






