「どこで」がレールのデフォルトの「順序」を上書きしています
概要
結果に基づいて 1 つのクエリを作成しようとしていますが、いくつかのタスクに別のクエリを適用しています。
ここでは、フィルターの 1 つである降順に基づいてデータを取得する 1 つのメソッド filter_based_on_ticket_creation があり、そのデータに基づいて、表示したい追加の詳細を提供する別のクエリを作成しています。
これが最も抜粋です、
def fetch_deallocations_based_on_department
department = params[:department]
deallocations = []
filter_based_on_ticket_creation(params).joins(:resource_info).where('resource_infos.department_name = ?',department).order(due_date: :asc).limit(5).each do |details|
deallocations.push([details.developer.name,details.due_date.present? ? details.due_date&.strftime('%d / %m / %Y') : 'Date not assigned'])
end
render json: deallocations
end
def filter_based_on_ticket_creation(params)
if (params[:q].present? && params[:q][:updated_at_lteq].present?)
@q.result.order(updated_at: :desc).limit(params[:q][:updated_at_lteq].to_i)
else
@q.result
end
end
ここには合計 32 件の割り当て解除レコードがあります。
irb(main):002:0> Deallocation.all.pluck(:id)
Deallocation Pluck (0.5ms) SELECT "deallocations"."id" FROM "deallocations"
=> [75, 24, 25, 26, 82, 27, 28, 74, 36, 41, 78, 58, 76, 53, 29, 40, 81, 30, 77, 23, 38, 39, 54, 68, 57, 70, 71, 72, 79, 73, 80, 83]
そこで今、最新の5または10のチケットを提供するフィルターを作成したいと思います。最新のデータを提供する1つのメソッド(filter_based_on_ticket_creation(params))を作成しました。updated_atに基づいて、最新の5レコードまたは10レコードを提供することを意味します ここで filter_based_on_ticket_creation(params) はいくつかのデータを返します
Deallocation Load (0.4ms) SELECT "deallocations".* FROM "deallocations" ORDER BY "deallocations"."updated_at" DESC LIMIT $1
pry(#<DeallocationsController>)> @filterd_deallocation.pluck(:id)
=> [75, 83, 82, 81, 40]
したがって、このフィルターを適用した後、2つのユースケースがあり、1つはこれらの5つのレコードを表示したいというもので、もう1つのユースケースでは、フィルターされたデータにWhereおよび結合条件を適用しています。
そして、fetch_deallocations_based_on_Department メソッドにある where 条件を適用しているとき、クエリをオーバーライドして別の出力が得られます。
@filterd_deallocation.joins(:resource_info).where('resource_infos.department_name = ?','ROR')
Deallocation Load (0.6ms) SELECT "deallocations".* FROM "deallocations" INNER JOIN "cims"."resource_infos" ON "cims"."resource_infos"."id" = "deallocations"."resource_info_id" WHERE (resource_infos.department_name = 'ROR') ORDER BY "deallocations"."updated_at" DESC LIMIT $1 [["LIMIT", 5]]
@filterd_deallocation.joins(:resource_info).where('resource_infos.department_name = ?','ROR').pluck(:id)
Deallocation Pluck (1.3ms) SELECT "deallocations"."id" FROM "deallocations" INNER JOIN "cims"."resource_infos" ON "cims"."resource_infos"."id" = "deallocations"."resource_info_id" WHERE (resource_infos.department_name = 'ROR') ORDER BY "deallocations"."updated_at" DESC LIMIT $1 [["LIMIT", 5]]
↳ (pry):4:in `deallocation_dashboard'
=> [75, 83, 40, 29, 53] # here additional 40,29,53 ids are coming
SQL で filter_based_on_ticket_params メソッドがこのクエリを作成していることがわかります。
ELECT "deallocations".* FROM "deallocations" ORDER BY "deallocations"."updated_at" DESC LIMIT $1
したがって、このクエリを適用すると
filter_based_on_ticket_creation(params).joins(:resource_info).where('resource_infos.department_name = ?',department).order(due_date: :asc).limit(5)
SQL クエリの実行順序により、「where」が「order」よりも優先されるため、デフォルトのクエリがオーバーライドされ、最初に「where」クエリが作成され、そのデータに基づいて「order」が作成されます。
SELECT "deallocations".* FROM "deallocations" INNER JOIN "cims"."resource_infos" ON "cims"."resource_infos"."id" = "deallocations"."resource_info_id" WHERE (resource_infos.department_name = 'ROR') ORDER BY "deallocations"."updated_at" DESC LIMIT $1
永続的なクエリが必要です。2 番目のクエリでは SQL フローの実行が変更されず、最初のクエリ データのみに基づいて結果が得られることを意味します。
解決策
Ruby on Rails についての知識がないので完全な回答はできませんが、先に進むのに役立つはずです。
あなたの質問は次のように理解しています。 最新の割り当て解除 ID [Query1] の結果があり、関連する部門の値に従ってこれらをフィルタリングしたいと考えています。 [クエリ2]
部門の最新の割り当て解除 ID をすべて表示する新しい結果は必要ありません。
最も簡単な方法は、query1 から目的の ID を指定することです。
# No idea if this is the way to write this in ruby
Deallocation.joins(:resource_info).where(deallaction.id: filterd_deallocation).where('resource_infos.department_name = ?',department)
これにより、次のようなクエリが生成されます。
SELECT "deallocations".*
FROM "deallocations"
INNER JOIN "cims"."resource_infos" ON "cims"."resource_infos"."id" = "deallocations"."resource_info_id"
WHERE
(resource_infos.department_name = 'ROR')
AND
(deallocations.id IN (75,83))
すでにお気づきのとおり、SQL の実行には厳密な順序があり、意図したとおりに動作します。 順序は、where によってすでにフィルターされた結果セットにのみ適用されます。 データを取得してフィルタリングする方法について、アプローチを再考することをお勧めします。