理解ActiveRecord的关联

理解ActiveRecord的关联
初学Rails时,觉得ActiveRecord很神奇,只要在model类中写上has_many, belongs_to等声明,就可方便地引用关联对象.这些关联声明还有很多选项,但开始并不理解(尤其对从未使用过ruby语言的人),只知道模仿着教程中的例子(以下的教程都指那本经典书:Agile web development with Rails)使用默认的选项.但是做实际项目时会发现默认选项不够用了,该怎么办?通过下面一个实际项目开发中的例子,就能真正理解model类的关联是怎么回事了.

场景:一个活动发布网站,要实现计划的发布和用户报名功能.报名还要分为已批准和待批准两种状态.
建模:(为表述方便对各表只列举最重要和有代表性的几个字段)很自然地首先会建立两个数据库表:users,plans.
users包含字段 id, name, password
plans包含字段 id, content, created_at (该记录创建时间,按 Rails 的约定该字段能自动维护), user_id (关联到users表,表示该计划的作者)

为了建立最基本的关联,只需要在模型文件中增加一个has_many和belongs_to:
# user.rb
class User < ActiveRecord::Base
has_many :plans
end
# plan.rb
class Plan < ActiveRecord::Base
belongs_to :user
end
增加这些声明的好处是什么?就是将来我得到一个plan对象时,可以用plan.user访问它的作者的信息;得到一个user对象时,可以用user.plans访问他发布的所有计划.多么简单!现在我要实现报名的功能了.
所谓报名,就是在plan和user之间再建立一种关联.这次是典型的多对多关联,因为一个计划可以有多个用户报名,而一个用户也可以报名参加多个计划.
多对多关联?教程上不是有介绍吗?马上模仿着建立一个关联表plan_user.包含字段 plan_id, user_id.
再按教程修改user.rb和plan.rb,增加相应的has_many:
# plan.rb
class Plan < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many : users
end
# user.rb
class User < ActiveRecord::Base
has_many :plans
has_and_belongs_to_many : plans
end
等等,User.rb里面怎么出现两个plans了,以后使用user.plans时到底是哪一个?静下来想一想,原来第一个has_many :plans表示一个用户发布的多个计划,第二个表示一个用户参加的多个计划.它们关联的对象虽然相同,但在业务逻辑上的意义是不同的.可是在代码中如何表示这种不同呢?我开始查关联的选项,发现有这么几个可用的选项:
:class_name, :join_table. 也就是说我可以改变关联的名称,但仍然关联到同一个表,修改如下:
# user.rb
class User < ActiveRecord::Base
has_many :plans
 has_and_belongs_to_many :plans_participated, :class_name => "lan"
end
这样一来,我就可以用user.plans来访问用户发布的计划,用user.plans_participated来访问用户参加的计划了.类似地,我修改了plan.rb中关联的名称以便我可以用plan.participants而不是plan.users来访问一个计划的所有参与者:
# plan.rb
class Plan < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :participants, :class_name => "User"
end
做到这里,我们稍微总结回味一下就不难发现,其实关于关联的各种声明就相当于给你的模型类动态增加属性,而has_many,belongs_to等声明其实是来自于ActiveRecord基类的一些方法,后面的选项是传给这些方法的参数.这些方法一被执行,就会给你的模型类动态增加一些属性.(在 Ruby的类定义里可以直接执行一些语句,就象HTML中写在<script>中的脚本一样,每当页面被装载就会被执行)
当我们写下 has__many :plans"这句话,就是在调用has_many方法,给User类增加了一个名为plans,类型为集合的一个属性.这个属性的返回值是来自于数据库表的,Rails的底层有足够信息知道该生成一条什么样的sql语句来返回相应的结果.甚至你还可以利用:finder_sql选项指定一条sql语句来替换默认的sql.这就是所谓关联声明的实质,也就是一些来自于基类的方法.一个方法调用是为了给类增加属性,动态地改变一个对象的行为?听起来有点陌生,其实在非脚本语言如C#里面事件机制也是类似的,button.clicked += new EventHandler(OnClick);这句话不就是通过对一个属性赋值而给button对象动态增加了一个方法供调用吗?
当然,Rails替你做的还不止是增加了属性,它还给你的模型类增加了一些操作关联表的方法,包括push,delete,find等(详见教程),省得你再去为plan_user表单独建立一个模型类了.

现在我的任务还没完成.我发现报名功能仅记录plan_id和user_id还不够,我还需要记录报名的时间,报名是否被批准,用户留言等信息.这些信息当然应该记录在报名表中.于是给plan_user表增加了几个字段created_at,confirmed,memo. 但是为了读写这几个字段,我还是得建立一个单独的模型类.不然更新这些信息时比较麻烦.加上这么些报名信息,其实报名表就应该是一个单独的数据实体了,在教程里David也提到:when a Join wants to be a model.说得就是这个意思,当一个多对多关联有很多属性时就应该做为一个model对待.于是我打算建立一个模型类.并且按模型类的约定把表名改成 joins,类名就叫Join (这里的join我是表示报名,而不是关联的意思):
#join.rb
class Join < ActiveRecord::Base
belongs_to :plan
belongs_to :user
end
这样我就有很多关于报名的方法可用了!而且将来要增加的批准方法也有地方放了.可是plan和user模型中的声明已经不再符合默认规则了,不要紧,利用一下:join_table选项:
class Plan < ActiveRecord::Base
belongs_to :user
has_many :joins
has_and_belongs_to_many :participants, :class_name => "User", :join_table => "joins"
end
class User < ActiveRecord::Base
has_many :plans
has_many :joins
has_and_belongs_to_many :plans_participated, :class_name => "lan", :join_table => "joins"
end
现在我想增加一个方法,得到所有已批准的报名.也就是所有confirmed = true的记录.难道要自己写一个方法,执行一个sql吗?不用.只要修改关联的声明,加一个 :condition => "confirmed = true"即可.但是我还想同时保留访问所有报名的功能怎么办?没问题,既然一个关联只不过是一个方法调用来增加一个属性,那为什么不可以调用多次,增加多个属性?
class Plan < ActiveRecord::Base
belongs_to :user
has_many :joins
has_many :confirmed_joins, :conditions => "confirmed = true"
has_many :unconfirmed_joins, :conditions => "confirmed = false"
has_and_belongs_to_many :participants, :class_name => "User", :join_table => "joins"
end
以后的用法举例如下:
用plan.user得到计划的发布者对象.
用plan.participants得到一个计划的所有参与者对象,进而访问参与者的姓名等信息.
用plan.confirmed_joins得到所有已批准的报名对象,进而访问报名时间,留言等信息.

到现在为止,我要的操作都通过关联声明来实现了,没有自己编写一个方法.而且对于关联表join,同时利用了单独模型类的好处和多对多关联的好处.真是鱼和熊掌兼得呀.
最后的结论就是,一个关联实际上就是基类的一个方法,你可以多次调用,任意组合.
反相器(inverter)和缓冲器(buffer)---附加与非门原理图 下面是对反相器(Inverter)和缓冲器(Buffer)从面积、驱动能力、时序等多个角度的详细对比,列出的是一般情况下的比较,具体情况可能会受到工艺节点、设计库和特定设计要求的影响。缓冲器(Buffer)是数字电路中常见的逻辑门之一,用于增强信号的驱动能力,而不改变信号的逻辑状态。如下图所示的CMOS反相器,由一个NMOS和PMOS组成,栅端gate相连作为输入端Vin,漏端相连作为输出端Vout,NMOS的源端接地,PMOS的源端接电源VDD.与反相器不同,缓冲器的输出与输入保持相同的逻辑状态。 阅读详情

相关推荐

Minio HTTPS证书配置实战:从申请到部署全流程

本文详细介绍了Minio HTTPS证书配置的全流程,从申请到部署,确保对象存储服务的安全性。内容包括证书类型选择、文件处理、服务配置调整及常见问题解决,帮助用户在生产环境中快速实现HTTPS加密传输,提升数据安全。

weixin_42638178的博客 407

mybatis-plus教程--ActiveRecord

完整代码 https://github.com/pbteach/mybatis-plus-test 完整讲义 http://www.pbteach.com/post/java_distribut/mybatis-plus-01/ http://www.pbteach.com/post/java_distribut/mybatis-plus-02/ 准备环境 创建数据库和表: -- 创建测试表 CR...

传智燕青 2218

基于YOLOv8的水果新鲜程度检测系统设计与实现

数据采集与预处理模块:负责收集水果图像数据并进行标注和增强深度学习模型:基于YOLOv8的目标检测模型新鲜度评估模块:根据检测结果评估水果新鲜程度用户界面:提供友好的交互界面系统集成:将各模块整合为完整系统水果新鲜程度检测需要包含多种水果在不同新鲜度状态下的图像数据集。:包含5种常见水果(苹果、香蕉、橙子、葡萄、草莓)在不同新鲜度下的图像包含约8,000张图像,分为新鲜和腐烂两类AgriVision:大型农业图像数据集,包含水果检测和分类任务Fruit-360:包含120种水果的高质量图像。

YOLO 426

MyBatis-Plus入门之ActiveRecord模式

ActiveRecord介绍 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录; 通常表的每个字段在类中都有相应的 Field; ActiveRecord 负责把自己持久化. 在 ActiveRecord 中封装了对数据库的访问,通过对象自己实现 CRUD,实现优雅的数据库操作。 ActiveRecord 也封装了部分业务逻辑。可以作为业务对象使用。 AR 之 insert dept 表设计: create database dept; use dept; CREATE TAB

花伤情犹在的博客 2985

MyBatis-Plus——使用ActiveRecord(AR)实现CRUD

MyBatis-Plus——使用ActiveRecord(AR)实现CRUD

贝尔摩德苦艾酒 7818

五、ActiveRecord(活动记录)

上一节我们学习基于 mybatis-plus 的条件构造器——QueryWrapper,这一节我们来学习一下mybatis-plus 的ActiveRecord(活动记录)。 在开始之前,我们先来了解一下什么是ActiveRecord(活动记录)? Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个...

runewbie的博客 1144

什么是ActiveRecord

 ActiveRecord是什么:1. 每一个数据库表对应创建一个类.类的每一个对象实例对应于数据库中表的一行记录; 通常表的每个字段在类中都有相应的Field;2. ActiveRecord同时负责把自己持久化. 在ActiveRecord中封装了对数据库的访问, 即CRUD; 3. ActiveRecord是一种领域模型 说实话,从去年开始用SubSonic, 我就一直有点困惑, ...

houzhe11的专栏 328

TheOdinProject 高级教程:深入理解 ActiveRecord 关联

你是否曾经在开发Rails应用时,为了处理复杂的数据关系而头疼不已?是否遇到过需要查询用户的所有文章、活动的所有参与者,或者实现多对多关系时的困惑?ActiveRecord关联(Associations)正是解决这些问题的利器,也是Rails框架最强大的特性之一。 本文将带你深入理解ActiveRecord关联的高级用法,从基础概念到复杂场景,通过实际代码示例和可视化图表,让你彻底掌握这一核心技...

gitblog_01188的博客 401

TheOdinProject私人活动平台开发指南:深入理解Rails高级表单与ActiveRecord关联

在现代Web应用开发中,用户期望一次性完成复杂操作,而不是反复提交多个表单。想象一下:你正在构建一个私人活动平台,用户需要同时创建活动、管理参与者、设置时间地点信息。如果每个操作都需要单独的页面和提交,用户体验将大打折扣。 这正是Rails高级表单与ActiveRecord关联大显身手的场景。通过`accepts_nested_attributes_for`、多对多关联和自定义表单构建,我们可以...

gitblog_01022的博客 249

CodeSmith 使用教程(15) 为Yii Framework 创建生成ActiveRecord的代码模板

在CodeSmith 使用教程(3): 自动生成Yii Framework ActiveRecord 我们通过SchemaExploer为Yii Framework从数据库生成简单的ActiveRecord类,没有考虑到表和表之间的关系。本例我们使用CodeSmith为Yii Framework创建一个通用的代码模板,可以使用上例介绍的SchemaExploer ,不过在查看CodeSmith自带

引路蜂移动软件 2603

Yii2模型的关联模型使用

Active Record 可以将相关数据集中进来, 使其可以通过原始数据轻松访问。 例如,客户数据与订单数据相关 因为一个客户可能已经存放了一个或多个订单。这种关系通过适当的声明, 你可以使用 $customer->orders 表达式访问客户的订单信息 这表达式将返回包含 Order Active Record 实例的客户订单信息的数组。 声明关联关系 你必须先在 Active Record 类中定义关联关系,才能使用 Active Record 的关联数据。 简单地为每个需要定义关联关系声明一个

Peak Xin's Blog 895

Yii2-多表关联的用法示例

本篇博客是基于《活动记录(Active Record)》中对于AR表关联用法的介绍。 我会构造一个业务场景,主要是测试我比较存疑的各种表关联写法,而非再次介绍基础用法。 构造场景 订单ar_order order_id 订单id(主键) user_id 用户id 用户ar_user user_id 用户id(主键) ...

382

Rails中的Active Record关联:初学者指南

作为Ruby on Rails开发人员,由于对象关系映射或ORM,我们不必太担心数据库中的操作。 ORM使我们可以更专注于业务逻辑,同时它代表我们处理数据库的操作。 了解关联对于创建可按预期方式运行并避免产生很大挫败感的Web应用程序至关重要。 在Rails中,关联是两个Active Record模型之间的连接。 假设有一个客户要求我们构建医院管理Web应用程序。 根据医院的需要,我们需要创...

编程故事的地方 253

rails 关联模型_Rails中的Active Record关联:初学者指南

rails 关联模型 作为Ruby on Rails开发人员,由于对象关系映射或ORM,我们不必太担心数据库中的操作。 ORM使我们能够更专注于业务逻辑,而它代表我们处理数据库的操作。 了解关联对于创建可按预期方式运行并避免产生很大挫败感的Web应用程序至关重要。 在Rails中,关联是两个Active Record模型之间的连接。 假设有一个客户要求我们构建医院管理网络应用程序。 根...

编程故事的地方 277

开源项目 activerecord_any_of 简介及新手指南

开源项目 activerecord_any_of 简介及新手指南 项目基础介绍 activerecord_any_of 是一个由 CSDN 公司开发的 InsCode AI 大模型提及的基于 Ruby 的开源项目。它旨在提供类似于 MongoDB 的 any_of 功能给 ActiveRecord,使得在进行数据库查询时能够更加灵活地构建动态的 OR 条件查询。此项目主要解决了在 ActiveRe...

gitblog_00610的博客 554

五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)

五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操) @目录五,MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)1. ActiveRecord 模式2. ActiveRecord介绍2.1 ActiveRecord实现3. SimpleQuery 工具类3.1 Simp...

weixin_30407555的博客 465

MyBatisPlus系列之ActiveRecord(活动记录)

上篇:MyBatisPlus系列之条件构造器 EntityWrapper 一、ActiveRecord(活动记录) 1、ActiveRecord概述 Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。 ActiveRecord 一直广受动态语言( PHP 、 Ruby 等)的喜爱,而 Java 作为准静态语言,对于 ActiveRecord 往往只能感叹其优雅,所以MP也在 AR 道路上进行了一定的探索 ..

weixin_39868387的博客 680

Mybatis-plus入门(五)之ActiveRecord使用

前言 本章主要讲述ActiveRecord的概述及使用 一、概述 ActiveRecord也属于ORM(对象关系映射)层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。 ActiveRecord的主要思想是: 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表...

Mikasa的博客 1465

ActiveRecord 是什么?

ActiveRecord是什么: 1. 每一个数据库表对应创建一个类.类的每一个对象实例对应于数据库中表的一行记录; 通常表的每个字段在类中都有相应的Field; 2. ActiveRecord同时负责把自己持久化. 在ActiveRecord中封装了对数据库的访问, 即CRUD; 3. ActiveRecord是一种领域模型(Domain Model), 封装了部分业务逻辑; ActiveR...

weixin_30951743的博客 176

MyBatis-Plus之ActiveRecord[基础增删改查操作]

ActiveRecord(简称AR)一直广受动态语言( PHP 、Ruby等)的喜爱,而java作为准静态语言,对于ActiveRecord往往只能感叹其优雅,所以我们也在AR道路上进行了一定的探索,希望大家能够喜欢~

心态的博客 1305

MyBatis-Plus 当中的 “ActiveRecord模式”和“SimpleQuery工具类”(详细实操)

ActiveRecord(活动记录,简称AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。ActiveRecord,一直广受解释型动态语言(PHP,Ruby 等)的喜爱,通过围绕一个数据对象进行 CRUD 操作。而Java作为准静态(编译型语言),对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索,仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅。

2401_87705025的博客 740

RISC-V版本计算机组成与设计课件.zip

基于RISC-V的计算机组成与设计课件

慧荣SMI方案SMI32X主控U盘修复量产工具

慧荣SMI方案SMI32X主控U盘修复量产工具快速修复采用慧荣芯片U盘量产拯救闪存的力量

上一篇: 解决“每个Y的最新X”SQL问题:
sungly
博客等级 码龄18年 0粉丝 3原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值