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

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 %>

分享到:
评论

相关推荐

    基于STM32单片机的激光雕刻机控制系统设计-含详细步骤和代码

    内容概要:本文详细介绍了基于STM32单片机的激光雕刻机控制系统的设计。系统包括硬件设计、软件设计和机械结构设计,主要功能有可调节激光功率大小、改变雕刻速率、手动定位、精确雕刻及切割。硬件部分包括STM32最小系统、步进电机驱动模块、激光发生器控制电路、人机交互电路和串口通信电路。软件部分涉及STM32CubeMX配置、G代码解析、步进电机控制、激光功率调节和手动定位功能的实现。 适合人群:对嵌入式系统和激光雕刻机感兴趣的工程师和技术人员。 使用场景及目标:① 适用于需要高精度激光雕刻的应用场合;② 为开发类似的激光雕刻控制系统提供设计参考。 阅读建议:本文提供了详细的硬件和软件设计方案,读者应结合实际应用场景进行理解,重点关注电路设计和代码实现。

    白色简洁风格的前端网站模板下载.zip

    白色简洁风格的前端网站模板下载.zip

    HarmonyException如何解决.md

    HarmonyException如何解决.md

    sdfsdfdsfsdfs222

    sdfsdfdsfsdfs222

    (177373454)html+css+js学习代码.zip

    html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+js学习代码 html+css+js学习代码html+css+js学习代码html+css+j

    usbgps2.apk

    usbgps2.apk

    白色简洁风格的家居建材网站模板下载.zip

    白色简洁风格的家居建材网站模板下载.zip

    EventEmitError解决办法.md

    EventEmitError解决办法.md

    白色简洁风格的工艺品展览企业网站源码下载.zip

    白色简洁风格的工艺品展览企业网站源码下载.zip

    matlab调制解调 OFDM OTFS 16qam qpsk ldpc turbo在高斯白噪声,频率选择性衰落信道下的误比特率性能仿真,matlab代码 OFDM simulink 包括添加保

    matlab调制解调 OFDM OTFS 16qam qpsk ldpc turbo在高斯白噪声,频率选择性衰落信道下的误比特率性能仿真,matlab代码 OFDM simulink 包括添加保护间隔(cp),信道均衡(ZF MMSE MRC MA LMSEE) 代码每行都有注释,适用于学习,附带仿真说明,完全不用担心看不懂

    build(1).gradle

    build(1).gradle

    贴标飞达sw16全套技术资料100%好用.zip

    贴标飞达sw16全套技术资料100%好用.zip

    其实这就是历年摘出来的

    其实这就是历年摘出来的

    地理遥感图像区域合并分割的大规模高效算法研究

    内容概要:本文针对大规模高分辨率遥感图像的处理问题,提出了一种基于图像分块的可扩展区域合并分割框架。传统的图像分块方法会导致分块边界上的伪影,影响最终结果。为解决这一问题,文中定义了稳定性边缘的概念,并给出了其数学表达,以确保分割结果与不分块时相同。此外,文章还介绍了一种高效的框架实现方法,用于在资源受限的设备上处理大型图像。 适合人群:从事遥感图像处理、计算机视觉及地理信息系统相关领域的研究人员和技术人员。 使用场景及目标:适用于需要处理大规模高分辨率遥感图像的应用场景,如环境监测、自然资源管理等。主要目标是提供一种能够高效处理大规模图像同时保持分割质量的方法。 其他说明:实验结果表明,所提出的算法不仅能够避免分块边界的伪影,而且能够在不同尺度下获得与不分块处理相同的分割结果。

    白色简洁风格的手机图片展示博客网站模板.rar

    白色简洁风格的手机图片展示博客网站模板.rar

    白色简洁风格的外科医疗整站网站源码下载.zip

    白色简洁风格的外科医疗整站网站源码下载.zip

    基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)

    基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计),本资源中的源码都是经过本地编译过可运行的,评审分达到98分,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、毕业设计、期末大作业和课程设计使用需求,如果有需要的话可以放心下载使用。 基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医疗领域问答系统实现源码+使用说明(毕业设计)基于python知识图谱医

    在线式缠绕膜机自动覆膜缠绕机sw16全套技术资料100%好用.zip

    在线式缠绕膜机自动覆膜缠绕机sw16全套技术资料100%好用.zip

    .archivetemp阅读天数.py

    .archivetemp阅读天数.py

Global site tag (gtag.js) - Google Analytics