2010-08-26 77 views
1

我想从控制器中提取逻辑,使其更加干燥。在Rails中处理类似以下内容的最佳方式是什么?在Rails中抽象ActiveRecord模型查询的最佳实践?

例如,而不是让在控制器的查询,我可以把它放在模型:

class SmoothieBlender < ActiveRecord::Base 
    belongs_to :user 

    def self.get_blenders_for_user(user) 
     self.where(["user_id = ?", user.id]) 
    end 
end 

或者它会更好地创建一个模块作为一个服务层,包括在每个使用它的模型?

module BlenderUser 
    def get_blenders_for_user(user) 
     SmoothieBlender.where(["user_id = ?", user.id]) 
    end 
end 

class SmoothieBlender < ActiveRecord::Base 
    include BlenderUser 
    belongs_to :user 
end 

class User < ActiveRecord::Base 
    include BlenderUser 
    has_many :smoothie_blenders 
end 

或者只是使其成为一个完整的服务类,可以从用户和Blender控制器访问?你会把这堂课放在哪里?

class BlenderService 
    def self.get_blenders_for_user(user) 
     SmoothieBlender.where(["user_id = ?", user.id]) 
    end 
end 

我是Ruby和Rails的新手,所以如果这是一个愚蠢的问题/语法不正确,请原谅我。提前致谢!

回答

5

我想创建一个named_scope(我认为这只是scope对Rails 3)

class SmoothieBlender < ActiveRecord::Base 
    belongs_to :user 

    scope :for_user, lambda { |user_id| 
     where("user_id = ?", user_id) 
    } 
end 

这样,您就可以拨打

SmoothieBlender.for_user(user.id) 
+0

啊,有道理!有点像.Net中的扩展。谢谢! – MunkiPhD 2010-08-26 19:41:07

+1

如果参数是以params形式传入的,请记住在其上使用.to_i。例如,在哪里(“user_id =?”,user_id.to_i) – 2010-08-26 23:00:44

+0

to_i会尝试解析它,如果它没有被消毒,我会失败吗? – MunkiPhD 2010-08-29 01:49:26