0

我有一个 Rails 应用程序,我想让它生成报告

我有一个日志、客户、用户和项目模型。

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

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

这是我最初的尝试:

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

问题是,如果我想要特定项目或客户的日志,则 params[:user_id] 为 nil 并且会出错

所以第二次尝试

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 语句,因为如果用户为 nil,它会出错,where("end_time IS NOT NULL")find 总是正确的。

发现现在是这样的

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

这行得通,但我真的不喜欢代码。

第三次尝试是我卡住的地方

我正在尝试通过将参数作为哈希传递给方法来为所有三个“user_try”方法工作的方法。

我怎样才能做到这一点?

4

2 回答 2

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 gem,它使过滤功能易于扩展。您可以轻松添加更多过滤器。如果它是 nil(你的用例),gem 也会忽略一个参数。

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
于 2013-04-26T10:47:57.400 回答
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
于 2013-04-26T11:33:08.127 回答