`
fei1985
  • 浏览: 35528 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
社区版块
存档分类
最新评论

rails 3 activerecord new interface

阅读更多

 

In short, passing options hash containing :conditions, :include, :joins, :limit, :offset, :order, :select, :readonly, :group, :having, :from, :lock to any of the ActiveRecord provided class methods, is now deprecated.

Going into details, currently ActiveRecord provides the following finder methods :

  • find(id_or_array_of_ids, options)
  • find(:first, options)
  • find(:all, options)
  • first(options)
  • all(options)
  • update_all(updates, conditions, options)

And the following calculation methods :

  • count(column, options)
  • average(column, options)
  • minimum(column, options)
  • maximum(column, options)
  • sum(column, options)
  • calculate(operation, column, options)

Starting with Rails 3, supplying any option to the methods above will be deprecated. Support for supplying options will be removed from Rails 3.2. Moreover, find(:first) and find(:all) ( without any options ) are also being deprecated in favour of first and all. A tiny little exception here is that count() will still accept a :distinct option.

The following shows a few example of the deprecated usages :

1
2
3
4
5
User.find(:all, :limit => 1)
User.find(:all)
User.find(:first)
User.first(:conditions => {:name => 'lifo'})
User.all(:joins => :items)

But the following is NOT deprecated :

1
2
3
User.find(1)
User.find(1,2,3)
User.find_by_name('lifo')

Additionally, supplying options hash to named_scope is also deprecated :

1
2
named_scope :red, :conditions => { :colour => 'red' }
named_scope :red, lambda {|colour| {:conditions => { :colour => colour }} }

Supplying options hash to with_scope, with_exclusive_scope and default_scope has also been deprecated :

1
2
3
with_scope(:find => {:conditions => {:name => 'lifo'}) { ... }
with_exclusive_scope(:find => {:limit =>1}) { ... }
default_scope :order => "id DESC"

Dynamic scoped_by_ are also going to be deprecated :

1
2
red_items = Item.scoped_by_colour('red')
red_old_items = Item.scoped_by_colour_and_age('red', 2)

New API

ActiveRecord in Rails 3 will have the following new finder methods.

  • where (:conditions)
  • having (:conditions)
  • select
  • group
  • order
  • limit
  • offset
  • joins
  • includes (:include)
  • lock
  • readonly
  • from

1 Value in the bracket ( if different ) indicates the previous equivalent finder option.

Chainability

All of the above methods returns a Relation. Conceptually, a relation is very similar to an anonymous named scope. All these methods are defined on the Relation object as well, making it possible to chain them.

1
2
lifo = User.where(:name => 'lifo')
new_users = User.order('users.id DESC').limit(20).includes(:items)

You could also apply more finders to the existing relations :

1
2
cars = Car.where(:colour => 'black')
rich_ppls_cars = cars.order('cars.price DESC').limit(10)

Quacks like a Model

A relation quacks just like a model when it comes to the primary CRUD methods. You could call any of the following methods on a relation :

  • new(attributes)
  • create(attributes)
  • create!(attributes)
  • find(id_or_array)
  • destroy(id_or_array)
  • destroy_all
  • delete(id_or_array)
  • delete_all
  • update(ids, updates)
  • update_all(updates)
  • exists?

So the following code examples work as expected :

1
2
3
4
5
6
7
8
red_items = Item.where(:colour => 'red')
red_items.find(1)
item = red_items.new
item.colour #=> 'red'

red_items.exists? #=> true
red_items.update_all :colour => 'black'
red_items.exists? #=> false

Note that calling any of the update or delete/destroy methods would reset the relation, i.e delete the cached records used for optimizing methods like relation.size.

Lazy Loading

As it might be clear from the examples above, relations are loaded lazily – i.e you call an enumerable method on them. This is very similar to how associations and named_scopes already work.

1
2
cars = Car.where(:colour => 'black') # No Query
cars.each {|c| puts c.name } # Fires "select * from cars where ..."

This is very useful along side fragment caching. So in your controller action, you could just do :

1
2
3
def index
  @recent_items = Item.limit(10).order('created_at DESC')
end

And in your view :

1
2
3
4
5
<% cache('recent_items') do %>
  <% @recent_items.each do |item| %>
    ...
  <% end %>
<% end %>

In the above example, @recent_items are loaded on @recent_items.each call from the view. As the controller doesn’t actually fire any query, fragment caching becomes more effective without requiring any special work arounds.

Force loading – all, first & last

For the times you don’t need lazy loading, you could just call all on the relation :


cars = Car.where(:colour => 'black').all

It’s important to note that all returns an Array and not a Relation. This is similar to how things work in Rails 2.3 with named_scopes and associations.

Similarly, first and last will always return an ActiveRecord object ( or nil ).

1
2
3
cars = Car.order('created_at ASC')
oldest_car = cars.first
newest_car = cars.last

named_scope -> scopes

Using the method named_scope is deprecated in Rails 3.0. But the only change you’ll need to make is to remove the “named_” part. Supplying finder options hash will be deprecated in Rails 3.1.

named_scope have now been renamed to just scope.

So a definition like :

1
2
3
4
class Item
  named_scope :red, :conditions => { :colour => 'red' }
  named_scope :since, lambda {|time| {:conditions => ["created_at > ?", time] }}
end

Now becomes :

1
2
3
4
class Item
  scope :red, :conditions => { :colour => 'red' }
  scope :since, lambda {|time| {:conditions => ["created_at > ?", time] }}
end

However, as using options hash is going to be deprecated in 3.1, you should write it using the new finder methods :

1
2
3
4
class Item
  scope :red, where(:colour => 'red')
  scope :since, lambda {|time| where("created_at > ?", time) }
end

Internally, named scopes are built on top of Relation, making it very easy to mix and match them with the finder methods :

1
2
3
red_items = Item.red
available_red_items = red_items.where("quantity > ?", 0)
old_red_items = Item.red.since(10.days.ago)

Model.scoped

If you want to build a complex relation/query, starting with a blank relation, Model.scoped is what you would use.

1
2
3
cars = Car.scoped
rich_ppls_cars = cars.order('cars.price DESC').limit(10)
white_cars = cars.where(:colour => 'red')

Speaking of internals, ActiveRecord::Base has the following delegations :

1
2
3
delegate :find, :first, :last, :all, :destroy, :destroy_all, :exists?, :delete, :delete_all, :update, :update_all, :to => :scoped
delegate :select, :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :to => :scoped
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :to => :scoped

The above might give you a better insight on how ActiveRecord is doing things internally. Additionally, dynamic finder methods find_by_name, find_all_by_name_and_colour etc. are also delegated to Relation.

with_scope and with_exclusive_scope

with_scope and with_exclusive_scope are now implemented on top of Relation as well. Making it possible to use any relation with them :

1
2
3
with_scope(where(:name => 'lifo')) do
  ...
end

Or even use a named scope :

1
2
3
with_exclusive_scope(Item.red) do
  ...
end

That’s all. Please open a lighthouse ticket if you find a bug or have a patch for an improvement!

UPDATE 1 : Added information about deprecating scoped_by_ dynamic methods.

UPDATE 2 : Added information about deprecating default_scope with finder options.

 

分享到:
评论

相关推荐

    Ruby on Rails:ActiveRecord模型操作教程.docx

    Ruby on Rails:ActiveRecord模型操作教程.docx

    Rails3的ActiveRecord 查询API.doc

    Rails 3.1 及以后版本的 ...总的来说,Rails 3 的 ActiveRecord 查询API引入了一种更模块化、更面向对象的方式来处理数据库查询,提高了代码的可读性和可维护性。开发者应逐渐适应并采用新的API,以充分利用其优势。

    rails_activerecord_lite

    Rails/ActiveRecord 精简版 ![预览] [预览]: ./docs/preview.png 描述 Rails/ActiveRecord Lite 是流行的 Ruby on Rails 框架的精简版。 这个应用程序的目的是更深入地了解 Rails 和 ActiveRecord 的工作原理,特别...

    userstamp, 这个 Rails 插件扩展ActiveRecord.zip

    userstamp, 这个 Rails 插件扩展ActiveRecord Userstamp插件( v-2.0 )概述Userstamp插件扩展了 ActiveRecord::Base,以添加对'创建者','更新程序'和'deleter'属性的自动更新。 它是基于 ActiveRecord::Timesta

    基于Java语言的Ruby on Rails ActiveRecord设计理念实现的设计源码

    该项目是采用Java语言实现的Ruby on Rails ActiveRecord设计理念的源码,总计包含46个文件,其中40个为Java源文件,其他包括Git忽略文件、许可证、Markdown文件、XML配置文件、数据库方言和驱动文件等。该设计旨在...

    Pro ActiveRecord Databases with Ruby and Rails.pdf

    ### ActiveRecord在Ruby与Rails中的高级应用 #### 一、引言 《Pro ActiveRecord Databases with Ruby and Rails》这本书深入探讨了如何使用ActiveRecord框架来高效地处理Ruby on Rails中的数据库操作。本书由Kevin ...

    actions_as_votable:为Rails Votable ActiveRecord

    充当可憎的角色(又称“喜欢的”角色) Acts as Votable是专门为Rails / ActiveRecord模型编写的Ruby Gem。 该宝石的主要目标是: 允许对任何模型进行投票,例如喜欢/不喜欢,赞成/反对等。 允许在任意范围内对任何...

    ActiveRecord-Without-Rails:只是在没有Rails的情况下使用ActiveRecord迁移的简单示例

    没有Rails的ActiveRecord 只是在没有Rails的情况下使用ActiveRecord迁移的简单示例您可以执行的任务: rake db:create rake db:migrate rake db:dropRails 5+的注意事项请注意,即使使用Rails 5,您也需要rake db:...

    Ruby on Rails中的ActiveRecord编程指南

    ### Ruby on Rails中的ActiveRecord编程指南 #### 一、引言 在Ruby on Rails框架中,ActiveRecord是一种用于实现数据库抽象层的对象关系映射(ORM)工具。它为开发人员提供了一种简单而强大的方式来处理数据库记录...

    workflow-activerecord:工作流库的 ActiveRecordRails 集成

    工作流库的 ActiveRecord/Rails 集成 工作流活动记录的主要+次要版本基于最旧的兼容 ActiveRecord API。 要在 Rails/ActiveRecord 4.1、4.2、5.0、5.1、5.2、6.0、6.1 中使用 ,请使用: gem 'workflow-...

    rails3教程

    ### Rails3教程知识点详解 #### 一、Rails3简介与核心原则 **Rails3**是Ruby on Rails框架的一个重要版本,它对之前的版本进行了大量的改进和优化,使其更加强大和灵活。Rails3的核心设计理念围绕着几个关键的概念...

    hashid-rails:在Rails应用程序ActiveRecord模型中使用Hashids(http:hashids.orgruby)

    在要启用哈希值的ActiveRecord模型中包括Hashid Rails。 class Model &lt; ActiveRecord :: Base include Hashid :: Rails end 继续使用Model#find输入hashid或常规的'ol id。 @person = Person . find ( params...

    Ruby Rails 3 Linda

    5. **生成器**:Rails提供了一系列命令行生成器,如`rails new`创建新项目,`rails generate controller`创建控制器,`rails generate model`创建模型等,这能快速构建应用结构。 6. **ActiveRecord查询接口**:...

    Rails 3 in Action

    《Rails 3 in Action》是2011年由Ryan Bigg撰写的一本关于Ruby on Rails框架的权威指南,专门针对当时最新的Rails 3.1版本进行了深入解析。这本书旨在帮助开发者充分利用Rails 3.1的强大功能,提升Web应用开发的效率...

    ruby on rails 3 tutorial.pdf

    你将学习ActiveRecord,它是Rails提供的一个ORM(Object-Relational Mapping)工具,允许你用Ruby代码操作数据库。 在控制器(Controllers)部分,你将学习如何处理HTTP请求,组织应用逻辑,并将数据传递给视图...

    ruby on rails 3

    Ruby on Rails 3 是一个基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(Model-...提供的文档如"Ruby192和Rails3.0.3的新征程.doc"和"rails3入门教程.pdf"等,将有助于深入理解这一框架及其在实际项目中的应用。

    rails-activerecord-model-rails-lab-v-000

    ActiveRecord模型Rails实验室 目标 手动创建迁移 手动创建模型 建立模型实例方法 建立模型 您可以在spec/models目录中找到此应用程序的测试套件,并使用以下命令运行它们: bundle exec rspec 。 该实验室进行测试以...

    Apress Pro ActiveRecord Databases with Ruby and Rails.pdf

    ### ActiveRecord在Ruby与Rails中的应用 #### 一、前言 《Pro ActiveRecord:Databases with Ruby and Rails》这本书深入探讨了如何使用ActiveRecord这一对象关系映射(Object Relational Mapping, ORM)工具来...

    Rails3常用命令行命令

    Rails3 是 Ruby on Rails 框架的一个版本,它提供了一系列强大的命令行工具,使得开发者可以快速地构建和管理Web应用。在本文中,我们将深入探讨Rails3中的常用命令,帮助你更高效地进行开发工作。 首先,新建一个...

    rails-activerecord-models-and-rails-readme-v-000

    Active Record是Rails用来管理应用程序模型方面的内置ORM。 什么是ORM? ORM是一个对象关系映射系统,从本质上讲,这是一个模块,它使您的应用程序能够以方法驱动的结构来管理数据。 这意味着您可以利用方法而不是...

Global site tag (gtag.js) - Google Analytics