从现在起,笔者会尝试将学习rails时的一些小技巧做成一份笔记,以一个系列的形式记录下来,每份笔记里面都会包含5个小tips,给自己复习用,也给需要的人一些帮助吧。
一、缓存实例变量
介绍一个快速提高性能的小技巧,只需要添加几个小指令即可。
def current_user
@current_user ||= User.find(session[:user_id])
end
在这里用到“||=”运算符,它能避免在多次调用current_user方法时,直接将User.find赋值给@current_user时造成的重复内存开销
二、使用动态的find_by方法
@task = Task.find(:all, :conditions => ['complete = ?',false])
@task = Task.find_by_complete(false)
第一个是惯用的查询一条complete中的值为false的方法,但是rails内建的find_by方法可以通过灵活的使用实现相同的功能,这样能增加代码的可读性。
但是遇到下面这种情况,我们该怎么办好呢?当查询顺序并不是默认的时候
@task = Task.find(:all, :conditions => ['complete = ?',false], :order => 'created_at DESC')
find_by可不是只能传一个参数进去哦,你可以这样
@task = Task.find_all_by_complete(false, :order => 'created_at DESC')
有没有很灵活的感觉?
三、通过关联来查询
首先在Project.rb has_many :tasks 在Task.rb 中 belongs_to :project
@project = Project.find(params[:id])
@task = @project.tasks.find_all_by_complete(false)
四、简化controller中的查询代码
在第二个tips中,
@task = Task.find_all_by_complete(false, :order => 'created_at DESC')
这段代码出现在controller中,但是这样的东西一多,会让你的controller显得臃肿不便于维护,我们觉得这样的一段代码似乎更加亲切一些
@task = Task.find_incomplete
可是在rails中并没有内建一个find_incomplete方法,于是我们便可以在Task.rb中加入
def self.find_incomplete
find_all_by_complete(false, :order => 'created_at DESC')
end
因为ruby的特性,我们并不需要返回什么,它会默认返回最后一个被操作的变量
五、使用with_scope
使用第四个tips很酷的样子,可是当我们需要通过关联来查询的时候,似乎就有些行不通了样子,因为加入了一些限制性的东西
@task = @project.task.find_all_by_complete(false) :limit => 20
这个时候就要用到with_scope语句了,我们修改一下Task.rb中的方法
def self.find_incomplete(options = {})
with_scope :find => options do
find_all_by_complete(false, :order => 'created_at DESC')
end
end
此时:find => options会把 :limit => 20 和下面的find_all...这段查询语句合并到一起,与此同时project_id也会被加入进来,这样使用起来就会特别灵活啦