理解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,布布扣,bubuko.com

时间: 2024-10-27 00:35:21

理解ruby on rails中的ActiveRecord::Relation的相关文章

Ruby On Rails中REST API使用示例——基于云平台+云服务打造自己的在线翻译工具

做为一个程序员可能在学习技术,了解行业新动态,解决问题时经常需要阅读英文的内容:而像我这样的英文小白就只能借助翻译工具才能理解个大概:不禁经常感慨,英文对学习计算机相关知识太重要了!最近发现IBM的云平台Blumemix,并且提供语言翻译的服务,感觉不错,就拿来研究学习一下:这里就分享一下我的研究学习过程,如何使用Ruby On Rails调用REST API打造自己的在线翻译工具,并演示如何把它发布到云平台上,让每个人都可以通过网络访问使用它. 应用效果展示 您可以通过点击效果图片的链接访问它

Elasticsearch 的_msearch介绍及在ruby on rails 中的使用

一.基本介绍 _msearch就是multi search API使用的末端,它可以在一个相同的api中去执行多个查询请求. 请求的格式类似于大部API的格式,它的请求格式如下: header\n body\n header\n body\n header可以包含要查询的索引(可以是多个索引),可选的映射类型,还有search_type, preference和routing. body可以包含指定的搜索请求(包括:query.aggregations.from.size等等). 例子见官网:h

ruby on rails 中使用phantomjs,并使用cookie

一.新建项目 rails new app --skip-bundle 完成后修改Gemfile文件:vim Gemfile 把source 修改成taobao或者ruby-china的源. 在这个文件里加入:gem 'phantomjs' 然后运行:bundle install 这样项目就新建完成了. phantomjs需要单独下载,如果不下载,这个gem运行的时候会自动下载,可能会比较慢. 二.生成pdf 创建一个controller在头部加上require 'phantomjs' 在form

ruby on rails 中使用pdfkit生成pdf

说是使用pdfkit,其实做工作的还是wkhtmltopdf. 一.新建项目 rails new mypdf --skip-bundle 进入项目:cd mypdf,打开Gemfile:vim Gemfile 修改source为https://ruby.taobao.com 添加:gem 'pdfkit' 运行bundle install 二.配置 在项目目录下的config/initializers里加上pdfkit.rb文件,修改内容为: PDFKit.configure do |confi

json格式在ruby和rails中的注意事项

#虚拟网络拓扑的json数据 def topodata #@vnic = Vnic.all #flash.now[:notice] = 'Message sent!' #flash.now[:alert] = 'Message sent!' simple_json = { nodes: [{ name: 'bob', age: "22", awesome: "true" }, { name: 'bob', age: 22, awesome:true }], link

ruby on rails 中使用phantomjs 生成pdf

一.新建项目 rails new app --skip-bundle 完成后修改Gemfile文件:vim Gemfile 把source 修改成taobao或者ruby-china的源. 在这个文件里加入:gem 'phantomjs' 然后运行:bundle install 这样项目就新建完成了. 二.生成pdf 创建一个controller在头部加上require 'phantomjs',在里面加入一个获取pdf的get方法:get_pdf 在这个方法里加入如下代码: Phantomjs.

Ruby on Rails 中你使用了Kaminari 后,千万不要再引入will_pagination 这个Gem 了

今日做开发的时候发现的这个问题 发现无论怎样配置都不能使用Kaminari 的Per 这个功能,分页大小也固定在了30 最开始还以为是Ransack 这个Gem 影响的,上网搜了很久发现没有 最后仔细检查,原来是Gemfile 里面包含了will_pagination    把它删除之后,一切恢复正常

ruby on rails模拟HTTP请求发生错误:end of file reached

在文章 Ruby On Rails中REST API使用示例--基于云平台+云服务打造自己的在线翻译工具 中,利用ruby的Net::HTTP发起http请求访问IBM Bluemix上的语言翻译服务时,提示:end of file reached 代码如下: auth = "c9819718-4660-441c-9df7-07398950ea44:qUvrJPqwsgOx"; surl = "https://" + auth + "@gateway.wa

Ruby on Rails服务器文件上传

最近看了下ruby on rails,试着把Dynamic Web TWAIN集成到ruby on rails中.这里分享下如何在rails中用几行代码搞定文件上传. 参考原文:How to Load, Scan and Upload Files with Ruby on Rails 作者:Desmond Shaw 翻译:yushulx 软件安装 Dynamic Web TWAIN 11.1 Ruby 2.1.7 Ruby Development Kit 在Windows上不要选择Ruby 2.