`
52jobs
  • 浏览: 11522 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

ActiveRecord

阅读更多
ActiveRecord 4新特性 http://www.oschina.net/translate/get-your-app-ready-for-rails-4?print

ActiveRecord 范围需要一个 Callable 对象。

在 Rails 4 中,所有 ActiveRecord 范围必须使用一个 callable 对象来定义:
#Rails 3.2
scope :recent, where(created_at: Time.now - 2.weeks)
#Rails 4
scope :recent, -> { where("created_at > ?", Time.now - 2.weeks).order("created_at desc") }
scope :active, -> { where(status: 'active') }

Activerecord-deprecated-finders 是 Rails 4.0 中默认提供废弃功能的依赖包,但它也将在 4.1 版本中被删除。因此你需要密切关注所有的警告信息,并开始修复这些警告。

Rails 指南 提供一个很有用的解释,关于在大多数情况下如何修改动态查找器:

    所有动态的方法除了 findby… 和 findby…! 外都已废弃,你可以使用如下的替代方法:

find_all_by_...改为 where(...).
find_last_by_...改为 where(...).last.
scoped_by_...改为 where(...).
find_or_initialize_by_...改为 where(...).first_or_initialize.
find_or_create_by_...改为 find_or_create_by(...) 或者 where(...).first_or_create.
find_or_create_by_...!改为 find_or_create_by!(...) 或者 where(...).first_or_create!.


#1 Caching with Instance Variables
@current_user ||= User.find(session[:user_id])


#2 Dynamic find_by Methods

@tasks = Task.find(:all, :conditions => ['complete = ?', false])
=>
@tasks = Task.find_all_by_complete(false)

@task = Task.find(:first, :conditions => ['complete =?', false], :order => 'created_at DESC')
=>
@task = Task.find_by_complete(false, :order => 'created_at DESC')


#3 Find Through Association

from
@tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])

to (推荐使用,用association 进行关联)
@project = Project.find(params[:id])
@tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])

 
#4 Move Find into Model
Move a find into the model to clean up the controllers and remove duplication. 
将 find 转移到model中,清洁controllers
from 

class TaskController < ApplicationController
  def index
    @tasks = Task.find_all_by_complete(:false, :order => "created_at DESC")
  end
end

to
class Task < ActiveRecord::Base
  belongs_to :project
  def self.find_incomplete
    find_all_by_complete(:false, :order => "created_at DESC")
  end
end


#5 Using with_scope

class Task < ActiveRecord::Base
  belongs_to :project

  def self.find_incomplete(options = {})
    with_scope :find => options do
      find_all_by_complete(false, :order => 'created_at DESC')
    end
  end
end
@tasks = @project.tasks.find_incomplete :limit => 20


#6 Shortcut Blocks with Symbol to_proc
projects.collect { |p| p.name } => ["Write another ASCIIcast", "Go out walking"]
projects.collect {&:name}       => ["Write another ASCIIcast", "Go out walking"]
projects.collect(&:name).collect(&:upcase)  => ["WRITE ANOTHER ASCIICAST", "GO OUT WALKING"]

projects.each {|project| project.save!}
==
projects.each(&:save!)


#16: Virtual Attributes (revised)
简介:对原生的attributes(collums),进行逻辑封装

schema.rb
create_table "products", :force => true do |t|
  t.string   "name"
  t.integer  "price_in_cents"
  t.datetime "released_at"
  ... ...
end

1、转换 {price_in_cents => price_in_dollars}


<%= f.label :price_in_dollars %>
<%= f.text_field :price_in_dollars %>

attr_accessible :name, :price_in_dollars
def price_in_dollars
  price_in_cents.to_d/100 if price_in_cents
end
def price_in_dollars=(dollars)
  self.price_in_cents = dollars.to_d*100 if dollars.present?
end

2、对 released_at 进行逻辑封装  {release_at => relese_at_text}

  attr_writer :released_at_text
  validate :check_released_at_text
  before_save :save_released_at_text
  def released_at_text
    @released_at_text || released_at.try(:strftime, "%Y-%m-%d %H:%M:%S")
  end
  
  def save_released_at_text
    self.released_at = Time.zone.parse(@released_at_text) if @released_at_text.present?
  end
  
  def check_released_at_text
    if @released_at_text.present? && Time.zone.parse(@released_at_text).nil?
      errors.add :released_at_text, "cannot be parsed"
    end
  rescue ArgumentError
    errors.add :released_at_text, "is out of range"
  end


3、支持创建新的 category
  <%= f.label :category_id %><br />
  <%= f.collection_select :category_id, Category.order(:name), :id, :name %>
  or create one:<%= f.text_field :new_category %>

  attr_accessible  :new_category
  attr_accessor :new_category  
  before_save :create_category  #在保存 product 前,先前所依赖的 category创建出来
  
  def create_category
    self.category = Category.create!(name: new_category) if new_category.present?
  end


#17、habtm-checkboxs
典型的多对多的关系 ,且使用关联表Categorization
class Product < ActiveRecord::Base
  has_many :categorizations
  has_many :categories, through: :categorizations
end

class Categorization < ActiveRecord::Base
  belongs_to :category
  belongs_to :product
end

class Category < ActiveRecord::Base
  has_many :categorizations
  has_many :products, through: :categorizations
end

rails consle分析
p=produc.first 	=> select "products".* from "products" limit 1
p.category_ids	=> select categories.id from categories inner join categorizations on categories.id=categorization.category_id where categorizations.product_id=1
p.category_ids=[1,2] =>
1、select * from categories where id IN (1,2)
2、select * from categories inner join categorizations on categoris.category_id=categorization.category_id where categorizations.product_id=1
3、insert into categorizations ... values category_id=1,product_id=1
4、insert into categorizations ... values category_id=2,product_id=1
p.categories	=>[#<Category id=1 .....>,#<Category id=2 ....>]
	

_form.html.erb

  <%= hidden_field_tag "product[category_ids][]", nil %>
  <% Category.all.each do |category| %>
    <%= check_box_tag "product[category_ids][]", category.id, @product.category_ids.include?(category.id), id: dom_id(category) %>
    <%= label_tag dom_id(category), category.name %>
  <% end %>
</div>



#15 Fun with Find Conditions
# When searching for null values the correct syntax would be priority IS NULL, not priority = NULL
Task.find(:all, :conditions => ["completed = ? AND priority = ?", false, 2]) 
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority = 2)


Task.find(:all, :conditions => ["complete=? and priority IS ?", false, nil])
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority is NULL) 

Task.find(:all, :conditions => ["complete=? and priority IN (?)", false, [1,3]])
Task.find(:all, :conditions => ["complete=? and priority IN (?)", false, 1..3])

Task.find(:all, :conditions => { :complete => false, :priority => 1 })
Task.find(:all, :conditions => { :complete => false, :priority => nil })

Task.find(:all, :conditions => { :completed => false, priority => [1,3] } 
SELECT * FROM "tasks" WHERE (completed = 'f' AND priority IN (1,3)

Task.find(:all, :conditions => {:completed => false, priority => 2..4})
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 2 AND 4 AND "tasks"."completed" = 'f') 

Task.find_by_priority(1..5)
SELECT * FROM "tasks" WHERE ("tasks"."priority" BETWEEN 1 AND 5) LIMIT 1



#14 Performing Calculations on Models

Task.first.priority      => 3
  SELECT * FROM "tasks" LIMIT 1
  
Task.sum(:priority)     => 12 
  SELECT sum("tasks".priority) AS sum_priority FROM "tasks"
  
Task.sum(:priority, :conditions => {:completed => false }) => 2 
  SELECT sum("tasks".priority) AS sum_priority FROM "tasks" WHERE (completed="f")
  
Task.minimum(:priority)   => 2 
  SELECT min("tasks".priority) AS min_priority FROM "tasks" 
  
Task.maximum(:priority)   => 5 
  SELECT max("tasks".priority) AS max_priority FROM "tasks"
  
Task.average(:priority).to_f  => 3.0 
  SELECT avg("tasks".priority) AS avg_priority FROM "tasks"
  
  #Using the methods through associations.
project = Project.first => #<Project id: 1, title: "A Project">   
project.tasks.sum(:priority, :conditions => {:completed => true})  => 10 
  
  SELECT sum("tasks".priority) AS sum_priority FROM "tasks" 
  WHERE ("tasks"."completed" = 't') AND ("tasks".project_id = 1)




#22 Eager Loading

<% @tasks.each do |task| %>
  <li><%= link_to task.name, task %> in <%= task.project.name %></li>
<% end %>


terminal

Project Load (0.2ms)   SELECT * FROM "projects" WHERE ("projects"."id" = 60) 
 CACHE (0.0ms)   SELECT * FROM "projects" WHERE ("projects"."id" = 60) 
 CACHE (0.0ms)   SELECT * FROM "projects" WHERE ("projects"."id" = 60) 
 CACHE (0.0ms)   SELECT * FROM "projects" WHERE ("projects"."id" = 60) 
 CACHE (0.0ms)   SELECT * FROM "projects" WHERE ("projects"."id" = 60)
 
解决方案
1、eager loading reduce the calls to the database even further. 
We enable it by making a change in the TasksController.


class TasksController < ApplicationController
  def index
    @tasks = Task.find(:all, :include => :project)
  end
end


2、Including More Than One Association

class Task < ActiveRecord::Base
  belongs_to :project
  has_many :comments
end

class TasksController < ApplicationController
  def index
    @tasks = Task.find(:all, :include => [:project, :comments])
  end
end

3、more complex associations. 

class Comment < ActiveRecord::Base
  belongs_to :task
  belongs_to :user
end

@tasks = Task.find(:all, :include => [:project, {:comments => :user }])


#23 Counter Cache Column
class Task < ActiveRecord::Base
  belongs_to :project, :counter_cache => true
  has_many :comments
end

migrations/006_add_tasks_count.rb
def self.up
  add_column :projects, :tasks_count, :integer, :default => 0
  Project.reset_column_information
  Project.find(:all).each do |p|
    Project.update_counters p.id, :tasks_count => p.tasks.length
  end
end
def self.down
  remove_column :projects, :tasks_count
end

console
p = Project.first
=> #<Project id: 61, name: "Project 1", created_at: "2009-01-26 20:34:36", updated_at: "2009-01-26 22:05:22", tasks_count: 20>
>> p.tasks.create(:name => "New task")
=> #<Task id: 1201, name: "New task", project_id: 61, created_at: "2009-01-26 22:24:13", updated_at: "2009-01-26 22:24:13">

The project’s counter cache has been updated.


#28 in_groups_of

ruby teminal

  a = (1..12).to_a   => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
  a.in_groups_of(4)  => [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
  a.in_groups_of(3)  => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
  a.in_groups_of(5)  => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, nil, nil, nil]]
  a.in_groups_of(5, false)  => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
  a.in_groups_of(5, 0)  => [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 0, 0, 0]]

rails

<table>
    <% @tasks.in_groups_of(4) do |tasks| %>
    <tr>
      <% tasks.each do |task| %>
      <td><%= task.name %></td>
      <% end %>
    </tr>
    <% end %>
</table>




#29 group_by Month
a = (1..20).to_a            => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
a.group_by { |num| num/5 }  => {0=>[1, 2, 3, 4], 1=>[5, 6, 7, 8, 9], 2=>[10, 11, 12, 13, 14], 3=>[15, 16, 17, 18, 19], 4=>[20]}

class TasksController < ApplicationController
  def index
    @tasks = Task.all
    @task_months = @tasks.group_by { |t| t.due_at.beginning_of_month }
  end
end

<% @task_months.keys.sort.each do |month| %>
<h2><%= month.strftime("%B %Y") %></h2>
  <% for task in @task_months[month] %>
    <p><b><%= task.name %></b> due at <%= task.due_at.to_date.to_s(:long) %></p>
  <% end %>
<% end %>

分享到:
评论

相关推荐

    ActiveRecord简单实例_activerecord.zip

    在Ruby on Rails框架中,ActiveRecord是一个至关重要的组件,它负责模型(Model)与数据库之间的交互。本实例将深入探讨ActiveRecord的基本用法,帮助理解如何在实际开发中有效地运用这个强大的工具。 首先,让我们...

    Pro ActiveRecord Databases with Ruby and Rails.pdf

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

    Castle.ActiveRecord (.NET FrameWork 2.0)

    Castle.ActiveRecord For .NET FrameWork 2.0 如果你想使用Castle.ActiveRecord,但又不想使用.NET Framework 3.0/3.5/4.0或更高版本,那么这个就是你所需要的,For .NET FrameWork 2.0,我整理了好久,自己从官方...

    NHibernate中文教程+activerecord

    Castle ActiveRecord是NHibernate ActiveRecord实现的一个版本,提供了额外的功能和方便性。它是一个AOP(面向切面编程)框架,能够自动管理对象的生命周期,包括事务、验证和持久化。 9. **最佳实践** 在实际...

    Castle.ActiveRecord 升级NHibernate到3.4.0GA

    Castle.ActiveRecord官方已经停止更新了,官方最高支持到NHibernate 3.1.0.4000,这个版本还有不少问题(例如:[NH-2213] - CLONE -Wrong parameters order in IQuery with SetParameterList and Filter)。...

    C# Castle.ActiveRecord CS源码示例教程.zip

    《C# Castle.ActiveRecord 源码示例教程》 Castle.ActiveRecord 是一款基于 C# 的轻量级对象关系映射(ORM)框架,它为 .NET 开发者提供了简化数据库交互的方式。这个教程主要围绕如何使用 Castle.ActiveRecord 在...

    简单Castle.ActiveRecord.Generator

    Castle.ActiveRecord.Generator 是一个基于 Castle ActiveRecord 框架的代码生成工具,它极大地简化了在.NET环境中使用ActiveRecord模式进行数据库操作的工作流程。ActiveRecord是面向对象持久化的一个设计模式,将...

    scala-activerecord-specs_2.9.2-0.2.3.zip

    描述中提到"scala-activerecord.zip",这可能是Scala Activerecord的主要库文件,而"scala activerecord scalatraactiverecord"则暗示Scala Activerecord可能与ScalatraActiverecord有关,ScalatraActiverecord是一...

    [IronRuby] C# 4.0调用ActiveRecord

    从提供的文件信息中,我们可以得知这篇博文主要讨论的是如何使用C# 4.0调用IronRuby中的ActiveRecord功能。不过由于博文链接和部分详细内容无法提供,知识点将基于文件信息部分和公共知识构建。 知识点一:IronRuby...

    MyBatisPlus的ActiveRecord实现CRUD示例代码

    在本示例中,我们将深入探讨MyBatisPlus如何通过ActiveRecord模式实现CRUD(创建、读取、更新、删除)操作。ActiveRecord是一种设计模式,它将数据库表中的每一条记录映射为一个对象,通过这个对象可以直接进行CRUD...

    Java敏捷持久层-ROR-ActiveRecord持久层框架的Java实现

    在Java世界里,虽然Hibernate和JPA等框架已经非常成熟,但Ruby on Rails(ROR)中的ActiveRecord模式也受到了不少Java开发者的青睐,并有了一些移植到Java平台的实现。 ActiveRecord是一种对象关系映射(ORM)模式...

    Ruby-SchemaPlus提供增强和扩展ActiveRecord的集合

    **Ruby-SchemaPlus:增强与扩展ActiveRecord的宝藏** 在Ruby on Rails开发中,ActiveRecord是核心组件之一,它作为ORM(对象关系映射)工具,使得开发者可以以面向对象的方式处理数据库操作。然而,尽管...

    Ruby-OccamsRecord缺少ActiveRecord的高效查询API

    Ruby是一种动态、面向对象的编程语言,而ActiveRecord是Ruby on Rails框架中的一个核心组件,它是一个对象关系映射(ORM)系统。ActiveRecord提供了一种简洁的方式将数据库操作与Ruby对象模型化,使得开发者可以方便...

    ActiveRecord 升级NHibernate到3.3.0GA

    将ActiveRecord中的NHibernate升级到3.3.0GA,排除编译的bug问题,保留ActiveRecord的完整功能,【Castle.ActiveRecord 升级NHibernate到3.4.0GA】的功能不完整!

    C# Castle.ActiveRecord Winform 源码示例教程

    Castle.ActiveRecord 的资料很多,但是WINFORM的没几个,于此我专门写了个例子献给初学Castle.ActiveRecord的童鞋们,希望这篇文档能够帮到你们。这个例子使用的是ACCESS数据库,从单表,一对多,多对多,数据绑定,...

    Python-OratorORM提供了一个简单而优美的ActiveRecord实现

    ActiveRecord是一种设计模式,它将数据库表的记录映射到对象,使得开发者可以通过对象的方法直接操作数据库。Orator ORM实现了这一模式,使得Python程序员可以方便地创建、查询、更新和删除数据库中的记录,而无需...

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

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

    ActiveRecord最终版(已更新NHibernate.3.4.1.4000)

    ActiveRecord最终版,由于ActiveRecord引用了ISet集合,Iesi.Collections.3.4.1.4000以后已经把ISet去掉了,所以ActiveRecord引用的NHibernate的版本的更新只能到3.4.1.4000此为止。 引用其他资源版本如下: ...

    activerecord-oracle-adapter-1.0.0.9250.gem

    activerecord-oracle-adapter-1.0.0.9250.gem 我找了很久才找到的,希望能解决部分像我这样,需要的同志!分就不要了,我就搬运了下,希望能解决部分人的问题!

    Castle ActiveRecord快速入门指南、ActiveRecord帮助文档

    Castle ActiveRecord 是一个开源框架,它是基于 .NET 平台的,用于简化对象关系映射(ORM)的过程。这个框架借鉴了 Ruby on Rails 中的 ActiveRecord 模式,将业务对象与数据库记录关联起来,使得开发者可以更专注于...

Global site tag (gtag.js) - Google Analytics