railscast 学习

#1 Caching with Instance Variables

尽量少用数据库查询,查询出来的东西能复用的要复用。怎么复用?保存在实例变量中。

1
2
3
4
5
class ApplicationController < ActionController::Base
def current_user
@current_user ||= User.find(session[:user_id]) # 这里面的逻辑还是有点绕的
end
end

#2 Dynamic find_by Methods

过时了,现在都直接用 find_by.

#3 Find Through Association

seeds.rb : 可以做些复杂的事情。

1
2
3
happy = Project.create(name: 'Be Happy')
happy.tasks.create(name: 'Buy a puppy', complete: false)
happy.tasks.create(name: 'Dance in the rain', complete: true)

找到第一个 project 中未完成的任务:

1
2
3
4
x = Task.where(project_id: 1).where(complete: false) #方法1

p = Project.find 1
p.tasks.where(complete: false)

#4 Move Find into Model

index action 中,排序查找什么的,不要放在 controller 中了,model 的事情交给 model 做,这样 controller 中如果有多个地方想用这个查询,放在模型中就可以复用这个查询代码了。
注意模型中,是类方法,方法名前面加 self。
新版本中用 scopes 取代了这种方法,代码量小的可以用,更简洁。

#5 scope

scope 将常用的查询条件定义成方法。

1
2
3
4
5
6
7
8
class Post < ActiveRecord::Base
scope :published, -> { where(published: true) }
end

class Post < ActiveRecord::Base
scope :created_before, ->(time) { where("created_at < ?", time) }
end
Post.created_before(Time.zone.now) #需要动态参数时,还是用方法比较合适。

#7 Layouts

动态布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class UsersController

layout :choose_layout

def index
end
def new
end

protected
def choose_layout
if current_user.admin?
“admin”
elseif current_user.user?
“user”
else
“application”
end
end
end

指定布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class UsersController
layout “my_layout”
end

class UsersController
layout nil
end

class UsersController
def index
render :layout => 'my_layout'
end
end

class UsersController
layout “my_layout”, : only => :method_name
layout “my_layout”, :except => [ :my_method1, :my_method2 ]

layout :my_layout, : only => :my_method
end