理解ruby on rails中的ActiveRecord::Relation
ActiveRecord::Relation是rails3中添加的。rails2中的finders, named_scope, with_scope 等用法,在rails3统一为一种Relation用法。
以下是返回ActiveRecord::Relation的方法:
bind
create_with
distinct
eager_load
extending
from
group
having
includes
joins
limit
lock
none
offset
order
preload
readonly
references
reorder
reverse_order
select
uniq
where
主要有以下优势:
1,惰性加载( Lazy Loading)
数据库并没有执行查询的动作,只有当真正使用这些数据的时候才会去查询数据库。
2,可以链式操作
Uers.where().where().order()....
一,实验验证惰性加载:
假设数据库中有一个posts表,表中有两个字段,id和title。
现在表中只有一条数据,id=1, title = old_name。
rails console
进入rails的控制台
p1 = Post.all
p2 = Post.order(:id)
p1.class #=> Array
p2.class #=> ActiveRecord::Relation
然后等待一会儿,去数据库中,将"old_name"改为"new_name"。这样的话,因为Post.all是立即加载数据,Post.order(:id)是惰性加载数据,所以改了
title之后,p1和p2的值应该是不相同的。
p1[0] => #<Post id: 1, title: "old_name", created_at: "2014-05-08 00:45:27", updated_at: "2014-05-08 00:45:27"> p2[0]
=> #<Post id: 1, title: "old_name", created_at: "2014-05-08 00:45:27", updated_at: "2014-05-08 00:45:27">
发现p1和p2的结果是相同的,Post.order(:id)并没有惰性加载数据,为什么呢?
原因是在rails的控制台中,会打印出语句的返回结果,也就使用了这些数据,所以这么修改p1和p2两行为:
p1 = Post.all;nil
p2 = Post.order(:id);nil
这样重新执行上边的流程,结果如下:
p1[0] => #<Post id: 1, title: "old_name", created_at: "2014-05-08 00:45:27", updated_at: "2014-05-08 00:45:27"> p2[0]
=> #<Post id: 1, title: "new_name", created_at: "2014-05-08 00:45:27", updated_at: "2014-05-08 00:45:27">
实验验证链式操作:
操作Relation实例的时候,会查询数据库。进入 activerecord-3.2.13\lib\active_record\relation.rb,找到inspect方法的定义:
def inspect
to_a.inspect
end
可以看出,调用先将Relation实例转换成数据,然后再将其inspect。
p2.inspoect
=> "[#<Post id: 1, title: \"new_name\", created_at: \"2014-05-08 00:45:27\", updated_at: \"2014-05-08 00:45:27\">]"
将inspect方法注释掉,然后看Relation实例中的内容
"#<ActiveRecord::Relation:0x463cbf0
@table=#<Arel::Table:0x4626e88 @name=\"posts\",
@engine=Post(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime),
@columns=nil,
@aliases=[],
@table_alias=nil,
@primary_key=nil>,
@klass=Post(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime),
@implicit_readonly=nil,
.......
@group_values=[],
@order_values=[:id],
@joins_values=[],
@where_values=[],
@having_values=[],
.......
@records=[]>"
可以看出Relation对象中根本就没有存储数据库中的内容,因为使用了order(:id)方法,所以@order_values=[:id]存储了查询信息。
对以Post.where("id = 1").order(:id),相应的Relation实例中值为:
@order_values=[:id],
@where_values=["id = 1"]
每一次链式操作都会在Relation中添加对应的查询条件,在使用的时候才去生成SQL语句,查询数据库。
总结:
知道了ActiveRecord::Relation的内部组织结构就非常好理解惰性加载和链式操作了,Relation让数据库操作更加优雅!
理解ruby on rails中的ActiveRecord::Relation的更多相关文章
- 【转】Ruby on Rails中select使用方法
在Ruby on Rails中真的有一堆Select helper可以用,我们经常容易混淆.常见的有三个..select, select_tag, collection_select(其余的什么sel ...
- ruby on rails 中render的
Ruby rails页面跳转代码如下: 1.render(:text => string) 2.render(:inline => string, [:type => "r ...
- Ruby on Rails中的Rake教程(Rake如何把我灌醉!)
下面是我们使用Rake任务的例子: 1.给列表中的用户发送邮件 2.每晚数据的计算和报告 3.过期或重新生成缓存 4.备份数据和svn版本(how's this : subversion reposi ...
- ruby on rails 中render的使用
最近写ror,因为比较菜,很多东西不知道,只能看一点查一点了 render 先上点搜集的常用方式 render :action => "long_goal", :layout ...
- json格式在ruby和rails中的注意事项
#虚拟网络拓扑的json数据 def topodata #@vnic = Vnic.all #flash.now[:notice] = 'Message sent!' #flash.now[:aler ...
- Ruby on Rails 中你使用了Kaminari 后,千万不要再引入will_pagination 这个Gem 了
今日做开发的时候发现的这个问题 发现无论怎样配置都不能使用Kaminari 的Per 这个功能,分页大小也固定在了30 最开始还以为是Ransack 这个Gem 影响的,上网搜了很久发现没有 最后仔细 ...
- ruby on rails模拟HTTP请求错误发生:end of file reached
在文章 Ruby On Rails中REST API使用演示样例--基于云平台+云服务打造自己的在线翻译工具 中,利用ruby的Net::HTTP发起http请求訪问IBM Bluemix上的sour ...
- 通过Ruby On Rails 框架来更好的理解MVC框架
通过Ruby On Rails 框架来更好的理解MVC框架 1.背景 因为我在学习软件工程课程的时候,对于 MVC 框架理解不太深入,只是在理论层面上掌握,但是不知道如何在开发中使用 MVC ...
- ubuntu 14.04中安装 ruby on rails 环境
环境:在win7 上Vmware虚拟机环境中安装的ubuntu 14.04 1. bundle install 时,报json错误可以看出是在安装nokogiri时遇到了问题,此时执行 sudo ap ...
随机推荐
- MAC 下用GCC编译报错:“Undefined symbols for architecture x86_64: ”
解决方法: 因为GCC编译的时候没有链接C++ standard library, 因此在编译的时候要加入符号 -lstdc++ 使用命令: gcc myprog.c -o myprog -lstdc ...
- Android开发-API指南-进程与线程
Processes and Threads 英文原文:http://developer.android.com/guide/components/processes-and-threads.html ...
- Flash与IE奇怪的关键字冲突
我有一个小小的swf文件,用来播放声音,加入到HTML后,在Firefox/chrome下播放正常,唯独IE8提示 消息: 对象不支持此属性或方法 行: 48 字符: 3 代码: 0 URI: ... ...
- sendmessage和postmessage的区别
BOOL PostMessage( HWND hWnd, // handle of destination window ...
- 【PL/SQL练习】基本的PL/SQL语句
1.无变量匿名快 begin dbms_output.put_line('Hello World'); end; 2.有变量的匿名块,定义变量: declare v_ename ); v_sal ,) ...
- Select的深入应用(1)
在子句中使用列的位置: 使用select语句创建新表: 在子句中使用列的别名: 注意,你的 ANSI SQL 不允许你在一个WHERE子句中引用一个别名.这是因为在WHERE代码被执行时,列值还可能没 ...
- IList,IQeurable,IEnumble和List 的区别
IList,IQeurable,IEnumble和List 的区别主要如下: 1.IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred exe ...
- TCP/IP详解学习笔记(13)-- TCP连接的建立与终止
1.TCP连接的建立 设主机B运行一个服务器进程,它先发出一个被动打开命令,告诉它的TCP要准备接收客户进程的连续请求,然后服务进程就处于听的状态.不断检测是否有客户进程发起连续 ...
- javascript代码复用模式
代码复用有一个著名的原则,是GoF提出的:优先使用对象组合,而不是类继承.在javascript中,并没有类的概念,所以代码的复用,也并不局限于类式继承.javascript中创建对象的方法很多,有构 ...
- C语言开源项目
值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...