云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > ActiveRecord(Ruby)

ActiveRecord(Ruby)

  • 62 次阅读
  • 3 次下载
  • 2025/6/1 1:41:38

order.name = \ order.save

不管怎样,在下面的例子里,Active Record对象只包含id,name,paytype,当对象被保存的时候仅仅只有这些字段被更新,注意如果你想要把对象保存到数据库,那么在使用find_by_sql方法时,一定要包含id字段。

orders = Order.find_by_sql(\ first = orders[0] first.name = \ first.save

另外,Active Record还提供了update_attribute()方法,该方法可以将Model对象的某个属性保存到数据库。 order = Order.find(123)

order.update_attribute(:name, \ order = Order.find(321)

order.update_attributes(:name => \ :email => \

我们可以把读取和更新结合在一起,使用update()方法或update_all(),update()方法使用一个id和一组属性,如果在数据库中对应的记录,就更新指定的属性,然后返回model对象。

order = Order.update(12, :name => \

也可以传递一组id或者属性和值的hash给update()方法,这样会更新所有匹配的记录,并且返回一组model对象。

最后,update_all()方法允许你指定给update语句指定Where条件,下面的例子给所有标题中含有java的商品涨价10%:

result = Product.update_all(\

这里的返回值依赖于具体的数据库适配器,很多数据库都返回被更新的记录数目。 下面我们看看save()和save!()这两个方法。

简单的save()方法在Model对象存在并且可以的保存的情况下返回true: if order.save # all OK else

# validation failed end

这样会导致你在所有调用save方法的地方都要加上检查,但是Active Record假定save方法是在Controler的Action的上下文中的,并且视图里的代码不进行这些检查。(这部分书上看不明白,不能确定)。

不管怎样,如果你需要在上下文环境中保存Model对象,并且想确定是否所有的错误都被处理了,你可以使用save!()方法,如果Model对象不能保存,那么这个方法会抛出一个RecordInvailid异常: begin

order.save!

rescue RecordInvalid => error # validation failed end

在学习Rails中的并发处理的处理前,我们先简单了解下并发处理的概念。 在有多个处理同时访问同一个数据库的应用程序中,可能会出现这样的情况,因为一个处理更新了数据库中的行,而使得另一个处理中持有的数据变得陈旧了。例如,A和B先后从数据库中提取了相同的数据,并都做了修改,这时B先将自己的修改更新会数据库,稍后,A将自己的修改更新回数据库,这时将会覆盖B所作的修改,当B再次提取数据库后,看到的是A修改的结果,而不是自己的。

一个解决办法就是将更新的表或者行进行锁定,防止其他程序进行更新或者访问,锁定可以完全避免并发的问题,也常称作悲观锁,但是在Web项目中,这个做法是行不通的,因为在同一个时间点上,可能会有很多个用户需要访问数据。

乐观锁并没有将数据锁定的外在表现,作为替代,在将修改写回到数据库之前,进行检查来确定一条记录是否已经被修改了。在Rails里的实现方法是,每和行都包含有一个版本号(version number),不管什么时候行被更新了,版本号就会被增加,当你在你的程序中进行一个更新操作时,Active Record检查行和Model的版本号,如果不匹配,将会放弃修改并抛出一个异常。

对于任何一个包含有integer型的字段lock_version的表,乐观锁都会默认的被启用,你可以把新行的这个字段初始为0,但是,如果你忘记了,Active Record也会替你完成。 我们来看看怎样实现乐观锁,我们创建一个名为counters的表: create table counters (

id int not null auto_increment, count int default 0,

lock_version int default 0, primary key (id) );

然后我给这个表创建一个行,将这个行读入到不同的Model中,并且在其中尝试更新, class Counter < ActiveRecord::Base end

Counter.delete_all

Counter.create(:count => 0) count1 = Counter.find(:first) count2 = Counter.find(:first) count1.count += 3 count1.save

count2.count += 4 count2.save

当我们运行上面的代码,会得到一个异常,Rails会放弃count2所作的修改,因为其中包含的已经是脏数据了。

如果使用了乐观锁,就需要在程序中处理这些异常,也可以禁用乐观锁: ActiveRecord::Base.lock_optimistically = false

关于乐观锁,可以参考Martin Flower所著的《企业应用解决方案及模式》一种中关于并发处理和工作单元(Work Unit)模式的内容,相信对Rails的并发处理机制会有更深的了解。

Active Record提供了两种方式进行删除操作。首先,有两个类级别的方法,delete和delete_all,这两个操作处在数据库层面上,delete()方法接收一个或一组和数据库对应的id,delete_all()方法删除所有符合指定条件的记录,如果没有指定条件,就会删除所有的

记录。方法的返回值和具体的数据库适配器相关,例如oracle返回被影响的行数。如果没有记录被删除,也不会抛出异常。 Order.delete(123)

User.delete([2,3,4,5])

Product.delete_all([\

另外,destory方法删除和数据库中行相对应的Model对象,这样会冻结这些对象,并且不能修改对象的值。

order = Order.find_by_name(\order.destroy

有两个类级别的destory方法,destory()方法接收一个或一组id,destory_all()方法接收删除条件。这两个方法都从数据库中读出对应的记录到Model对象,并且对这个对象调用实例级别的destory()方法,而且不返回有意义的信息。 Order.destroy_all([\

为什么我们同时需要delete和destory方法呢?delete方法绕过了一些Active Record的回调(callback)和验证函数,而使用destory则不会,通常我们使用destory方法来确保我们的数据库是一致的,并且不会破坏Model中所包含的业务逻辑。 很多程序使用的数据库都包含有多个表,而且通常一些表之间还有关联关系,订单常含有多个条目,而一个条目又关联到一种商品,一个商品可能又属于多个商品分类,一个商品分类里又包含有多个不同的商品。

在数据库中,这些关联表现为使用主键值把表关联起来,也就是外键,但是这属于底层的范畴,我们需要处理Model对象间的关联,而不是数据库中的列和键。如果一个订单含有多个条目,我们需要有办法来维持,处理它们的关系,如果一个条目引用到一种商品,我们或许想这样做:

price = line_item.product.price 而不愿像下面这样麻烦:

product_id = line_item.product_id product = Product.find(product_id) price = product.price

Active Record可以帮助我们,作为ORM的一部分,Active Record将低级别的数据库中的外键转换成高级别的对象间的映射。处理了三种基本情况: A表中的一条记录和B表的零条或一条记录相关联。 A表中的一条记录和B表的任意多条记录相关联。 A表中的任意多条记录和B表的任意多条记录相关联。

下面我们来看看怎样创建外键(Foreign Key),我们使用下面的DDL来创建表,它们之间指定了关联:

create table products (

id int not null auto_increment, title varchar(100) not null, /* . . . */

primary key (id) );

create table orders (

id int not null auto_increment, name varchar(100) not null,

/* ... */

primary key (id) );

create table line_items (

id int not null auto_increment, product_id int not null, order_id int not null,

quantity int not null default 0, unit_price float(10,2) not null,

constraint fk_items_product foreign key (product_id) references products(id), constraint fk_items_order foreign key (order_id) references orders(id), primary key (id) );

在上面的DDL中,订单和条目关联,条目又关联到具体的商品。注意这里的命名约定,外键的名字product_id,product是products表的单数形式,然后再加上表的主键名字_id构成外键名。

上面的DDL中,订单和条目是一对多的关系,还有一种是多对多关系,例如,一种商品属于多个商品分类,一个商品分类又含有多种商品。对这种情况,通常我们使用第三个表,叫做结合表,这个表只包含两个要关联的表的id: create table products (

id int not null auto_increment, title varchar(100) not null, /* . . . */

primary key (id) );

create table categories (

id int not null auto_increment, name varchar(100) not null, /* ... */

primary key (id) );

create table categories_products ( product_id int not null, category_id int not null,

constraint fk_cp_product foreign key (product_id) references products(id), constraint fk_cp_category foreign key (category_id) references categories(id) );

注意结合表的命名,在这里Rails的约定为两个表名,中间用下划线分开,表名按照字母排序,Rails会自动找到categories_products表将categories表和products链接起来,如果你没有按照约定,那么就要自己声明,以便Rails能够找到它。

Rails支持三种表间关联关系,一对一,一对多,多对多,你需要在Model中加入声明来标识这些关联:has_one,has_many,belongs_to,has_and_belongs_to_many。

一对一关联关系可能存在于象订单和发票这样的关系,一个订单只能有一个发票,在Rails中,我们这样指明:

搜索更多关于: ActiveRecord(Ruby) 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

order.name = \ order.save 不管怎样,在下面的例子里,Active Record对象只包含id,name,paytype,当对象被保存的时候仅仅只有这些字段被更新,注意如果你想要把对象保存到数据库,那么在使用find_by_sql方法时,一定要包含id字段。 orders = Order.find_by_sql(\ first = orders[0] first.name = \ first.save 另外,Active Record还提供了update_attribute()方法,该方法可以将Model对象的某个属性保存到数据库。 order = Order.find(123) order.update_attribute(:name, \ order = Order.find(321)

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com