2013-04-26 49 views
0

我有一个Rails应用程序,我希望把它生成一个报告一个复杂的Rails查找基于协会有时ID是零

我有一个日志,客户,用户和工程款。

日志可以属于项目和客户,并且始终属于用户。

当我生成报告。我可以例如选择用户并获取该用户的所有日志。当我选择用户和项目时,我想获取与用户和项目关联的日志。

这是我最初的尝试:

Log.where(user_id: params[:user_id],project _id: params[:project_id],customer_id: params[:customer_id] 

的问题是,如果我想为一个特定项目或客户的日志中,PARAMS [:USER_ID]是零,它的错误了

所以谢胜利尝试

class Log < ActiveRecord::Base 
    def self.user_try(user) 
     if user 
      where(user_id: user) 
     else 
      where("end_time IS NOT NULL") 
     end 
    end 
    #corresponding methods for project and customer 
end 

我必须有丑陋的if..else语句的原因,如果用户是零它的错误了where("end_time IS NOT NULL")发现只是总是如此。

立即查找是这样

Log.user_try(params[:user_id]) 
    .project_try(params[:project_id]) 
    .customer_try(params[:customer_id]) 

这工作,但我真的不喜欢的代码。

第三次尝试是我在哪里卡住

我努力让自己在方法通过将PARAMS中的方法作为哈希确实为所有三个“user_try”方法的工作。

我该怎么做?

回答

0

在控制器

Log.try_find_logs(user_id: params[:user_id], 
        project_id: params[:project_id], 
        customer_id: params[:customer_id]) 

在该模型中一地图上的散列。这给了我一个数组的数组。我注入了&运算符,并获得具有正确ID的日志,即使我没有一些参数。

class Log < ActiveRecord::Base 
def self.try_find_logs(options) 
    a = options.map do |k,v| 
     where(k => v) 
    end 
    a.inject(:&) 
end 
end 
1
@logs = Log.all 
@logs = @logs.where(:user_id => params[:user_id]) unless params[:user_id] 
@logs = @logs.where(:project_id => params[:project_id]) unless params[:project_id] 
@logs = @logs.where(:user_id => params[:customer_id]) unless params[:customer_id] 

只是万一你不知道这一点,上面只会触发一个数据库查询。

我会建议你使用has_scope宝石,这使得过滤功能易于扩展。您可以轻松添加更多过滤器。如果它是零(你的用例),那么宝石会忽略一个参数。

class Log < ActiveRecord:Base 
scope :user, proc { |u_id| where(:user_id => u_id) } 
... 
end 

class LogsController < ApplicationController 
    has_scope :user 
    def index 
    @logs = apply_scopes(Log) 
    end 
    ... 
end