3

我正在为我的 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 undefinedAND之类的错误,我连这个简单的重构都没有完成method request undefined。我不确定为什么这些动作不能在模型类中使用。

有人可以解释这背后的原因并指导我找到一些可以帮助我顺利完成重构过程的好文档吗?

非常感谢。

4

2 回答 2

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
于 2013-01-07T10:26:39.970 回答
1

您不能将控制器中的每个代码都移动到模型中。会话处理和请求之类的一些代码仅适用于控制器。它们在模型内部不可用。只有仅限于模型级处理的处理代码才需要在模型中。

以下是重构 Rails 代码的最佳书籍,

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

于 2013-01-07T07:11:13.687 回答