Rails 的超小型筆記 (4)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# attr_accessible 的作用
防止經由 FORM 提交非法的欄位進而可以改動資料
如 user 中有 role 欄位,如無防止則可以通過以下方法修改

# 原來
<form action="" method="post">
<input type="text" name="email" value="@" />
</form>

# 非法修改
<form action="" method="post">
<input type="hidden" name="role" value="admin" />
<input type="text" name="email" value="@" />
</form>
1
2
3
4
5
6
7
	
# Devise 中錯誤訊息的 resource i18n 修改
於 config/locales/zh-TW.yml 中加入相對應的表名

activerecord:
models:
user: "用戶"
1
2
3
4
5
6
7
# Devise 中相對應的 text_field 或其他欄位名稱 i18n 修改
於 config/locales/zh-TW.yml 中加入對應的資料表下的欄位

activerecord:
attributes:
user:
current_password: "目前密碼"
1
2
3
4
5
6
7
8
9
10
	      
# 分頁時出現 undefined method `current_page'
1. 因為直接執行了整個 SQL Query 而沒有提供後繼分頁時用的 Object
2. 例子

# 正常
@q = Question.order("created_at DESC").page(params[:page])

# 不正常,因為 all 是已經發出了 SQL 的查詢指令,@q 不再是待 Build 來的
@q = Question.order("created_at DESC").page(params[:page]).all
1
2
3
4
5
6
7
8
9
10
11
12
13
14
	
# 將找不到記憶的錯誤轉向到 404 頁面
於 application_controller.rb 中加入

rescue_from ActiveRecord::RecordNotFound, :with => :render_404

def render_404(exception = nil)
if exception
logger.info "Rendering 404: #{exception.message}"
end

@page_title = "404"
render 'errors/404', :status => 404
end
1
2
3
4
5
	
# 如果需要 Share Controller 之間的代碼
1. 將需要 Share Controller 中的相同代碼包成 Method
2. 並放於 application_controller.rb 內.因為各個 controller 都會繼承他
3. 之後就可以在各個 controller 中調用
1
2
3
4
5
6
7
8
9
10
# 需要為模版中鑲入的子模版傳入參數可以用
1. 主模版

<% for abc in @abc.all %>
<%= render :partial => "shared/abc_row", :locals => { :abc => abc } %>
<% end %>

2. 子模版

<%= abc.id %>
1
2
3
4
5
6
7
8
9
	
# Scope 的應用
1. 於 model 中定義查詢的條件或各樣的資料,如

scope :hot_desc, :order => "try_count DESC"

2. 之後可以控制器中使用,如

Abc.hot_desc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 將查詢變為模型內的自身函數 (Static Method)
1. 通過於 model 中加入 def self.method_name 如

def self.find_random_user(limit)
self.find_by_sql(["
SELECT * FROM users
WHERE id >= (abs(random()) % (SELECT max(id) FROM users))
LIMIT ?;
", limit])
end

2. 於控制器中調用

@random_users = User.find_random_user(10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	
# 簡化實體化後的一些 SQL 處理,可以通過自寫的函數
1. 通過於 model 中加入 def method_name 如 (其中 answer_count 和其他兩個都是 model 的欄位)

def all_counter_is_zero
answer_count == 0 && right_count == 0 && wrong_count == 0
end

def increase_vote
self.update_attribute(:vote, self.vote + 1)
end

2. 於控制器中使用

@model = Model.find(1).frist
@model.all_counter_is_zero

@model = Model.new
@model.increase_vote
1
2
3
4
5
6
7
8
9
	
# 記錄/alert 錯誤訊息
1. 於程式中直接使用

y 變量/物件

2. 使用 logger 物件

logger.info(@right_list)
1
2
3
4
5
6
7
8
9
10
11
12
	
# 回傳 JSON 格式
直接通過以下方式回傳

respond_to do |format|
format.json {
render :json => {
:status => status,
:message => message
}
}
end
1
2
3
4
5
6
7
8
9
10
11
12
13
	
# Routes 的如有 :symbol
1. 如下

get '/something/:sort_type' => 'home#index', :as => :something_sort_type

2. 則雖要在呼叫時傳入參數

# 錯誤,會出現找不到路由
something_sort_type_path

# 正確
something_sort_type_path("old")
1
2
3
4
5
6
7
8
9
10
	
# 如果路由路本身是作為廣泛配對,則固定的必須於上面
1. 如

get '/profile/:user_id' => 'profile#user', :as => :user_profile_index

2. 則應如下才能前往 something,否則會找不到對應的 action

get '/profile/something' => 'profile#something', :as => :something_profile_index
get '/profile/:user_id' => 'profile#user', :as => :user_profile_index
1
2
3
4
5
6
7
8
9
10
	
# 加上獨特的方法到 resource 裡面可通過
1. 如下 (加入 def answer, def vote, 而七個方法中只保留 create 方法)

resources :home, :only => [:create] do
collection do
post :answer
post :vote
end
end
1
2
3
	
# form_for 中沒有輸出
1. 檢查 <% %> 裡面是否少寫了 <%= %> 等於