0

Rails アプリがあり、レポートを生成したい

Log、Customer、User、および Project モデルがあります。

ログはプロジェクトと顧客に属することができ、常にユーザーに属します。

レポートを生成するとき。たとえば、ユーザーを選択して、そのユーザーのすべてのログを取得できます。ユーザーとプロジェクトを選択すると、ユーザーとプロジェクトに関連付けられているログを取得したいと考えています。

これは私の最初の試みでした:

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")検索は常に true であるというエラーが発生します。

発見は今このようになっています

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

これは機能しますが、コードが本当に好きではありません。

3回目の試行は私が立ち往生している場所です

メソッドにパラメーターをハッシュとして渡すことにより、3つの「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]

これがわからない場合に備えて、上記は 1 つのデータベース クエリのみを起動します。

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 に答える