2013-04-26 48 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