2013-01-07 41 views
3

我正在爲我的Rails應用程序進行重構。我已經閱讀了很多關於將控制器邏輯移動到模型的文章,但是當我嘗試時我遇到了一些問題。Rails將控制器邏輯轉換爲模型

我需要幫助

  1. 瞭解是否存在以下錯誤的原因
  2. 要知道我應該讀什麼文件,成功地將我的所有控制器邏輯模型

因爲我還沒有爲我的應用程序做過任何重大的重構,所以首先嚐試了一個簡單的重構。

PostsController(前)

def create 
    @post = Post.create(params[:post]) 
    @post.user_id = session[:user_id] 
    @post.num_likes = 0 
    @post.num_dislikes = 0 
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(request.remote_ip) 
    @post.user_location = @geoip.country_name 
end 

PostModel(新)

before_save :initialize_post 

def initialize_post 
    self.user_id = session[:user_id] 
    self.num_likes = 0 
    self.num_dislikes = 0 
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(request.remote_ip) 
    self.user_location = @geoip.country_name 
end 

PostsController(新)

def create 
    @post = Post.create(params[:post]) 
end 

但是,由於session undefinedmethod request undefined等錯誤,我甚至沒有做到這一簡單的重構。我不確定爲什麼這些行爲不能用在模型類中。

有人可以解釋這個背後的原因,並指示我一些很好的文檔,這將幫助我通過一個平滑的重構過程?

非常感謝。

回答

3

爲了您的控制器我會做這樣的事情..

def create 
    @post = Post.new(params[:post]) 
    @post.user_id = session[:user_id] 
    @post.ip_address = request.remote_ip 
    @post.save 
end 

和模型..類似的東西;

attr_accessor :ip_address 
before_create :set_default_values 
before_save :geo_locate 

private 

def geo_locate 
    @geoip = GeoIP.new("#{Rails.root.to_s}/db/GeoIP.dat").country(self.ip_address) rescue nil 
    self.user_location = @geoip.country_name unless @geoip.blank? 
end 

# This only runs when a new record is created. Alternatively, look into setting a default value on your database columns! 
def set_default_values 
    self.num_likes = 0 
    self.num_dislikes = 0 
end 
1

您無法將控制器中的每個代碼移動到模型中。某些代碼(如會話處理和請求)僅限於控制器。它們在模型中不可用。只有處理僅限於模型級處理的代碼才需要模型化。

以下是重構Rails代碼最好的書,

http://www.amazon.com/Rails-AntiPatterns-Refactoring-Addison-Wesley-Professional/dp/0321604814

+0

我明白了。謝謝!但是除了這本書還有其他來源嗎? –

+0

您可以在重構時查找軌道轉換劇集,這是很好的開始。 –