我們應該儘量把跟資料庫有關的操作都搬回model,例如以下:幾個情況:
舉例:
當user發佈post時就可以根據內容多寡得到虛擬幣,最多500元,controller中寫法如下
post_controller.rb
def publish
@post = Post.find(params[:id])
@post.update(:is_published => true)
if @post.content.size < 500
@post.owner.money += @post.content.size
else
@post.owner.money += 500
end
redirect_to post_path(@post)
end
post_controller.rb
def publish
@post = Post.find(params[:id])
@post.publish
redirect_to post_path(@post)
end
model/post.rb
def publish
self.update(:is_published => true)
if self.content.size < 500
self.owner.money += self.content.size
else
self.owner.money += 500
end
end
class PostsController < ApplicationController
def create
@post = Post.new(params[:post])
@post.user_id = current_user
@post.save
end
end
class PostsController < ApplicationController
def create
@post = current_user.posts.build(params[:post])
@post.save
end
end
class User < ActiveRecord::Base
has_many :posts
end
scope access可以讓我們避免掉許多不必要的判斷,請直接看例子,此例使用current_user就可以省去判斷user的情況。
class PostsController < ApplicationController
def edit
@post = Post.find(params[:id])
if @post.user != current_user
flash[:warning] = 'Access denied'
redirect_to posts_url
end
end
end
class PostsController < ApplicationController
def edit
@post = current_user.posts.find(params[:id])
end
end
有時候由於表單的設計方式與model內的attribute不同,我們會需要將表單的資料拆解後再送給資料庫,例如資料庫內有'first_name'和'last_name'但是表單只有'full_name'
不好的寫法:
在controller裡面將params的資料切開,並存進資料庫
<% form_for @user do |f| %>
<%= text_field_tag :full_name %>
<% end %>
class UsersController < ApplicationController
def create
@user = User.new(params[:user])
@user.first_name = params([:full_name]).split(' ', 2).first
@user.last_name = params([:full_name]).split(' ', 2).last
@user.save
end
end
比較好的寫法:
class User < ActiveRecord::Base
# 這個method可以讓表單以後要讀取full_name的attribute時可以拿到資料
def full_name
[first_name, last_name].join(' ')
end
# 這個method讓post回來的full_name拆解成first_name和last_name儲存
def full_name=(name)
split = name.split(' ', 2)
self.first_name = split.first
self.last_name = split.last
end
end
<% form_for @user do |f| %>
<%= f.text_field :full_name %>
<% end %>
class UsersController < ApplicationController
def create
@user = User.create(params[:user])
end
end
如此一來controller變得超乾淨!!
6.Use model callback
7.Replace Complex Creation with Factory Method
8.Nested Model Forms