【发布时间】:2017-08-10 17:39:54
【问题描述】:
我正在尝试创建一个范围方法,该方法仅查询最近更新过的记录(或其关联模型最近更新过)。我相信生成的 SQL 语句看起来不错,但是当应该有一些结果时我没有看到任何结果。感谢您的帮助!
控制器
class Api::V1::EncountersController < ApplicationController
respond_to :json
def index
if params.has_key?(:datestart)
...
elsif params.has_key?(:updated_since)
date = Date.parse(params[:updated_since])
respond_with(Encounter.by_updated_since(date),
:include => [:facility, :physician, :encounter_type, :group, :provider, :insurance],
:except => [:facility_id, :physician_id, :encounter_type_id, :group_id, :provider_id, :insurance_id])
else
...
end
end
型号
class Encounter < ApplicationRecord
validates :encounter_type, :physician, :facility, :datetime_start_utc_scheduled, :procedures, :presence => true
belongs_to :encounter_type
belongs_to :physician
belongs_to :facility
belongs_to :insurance
belongs_to :group, optional: true
has_many :encounter_procedures, :dependent => :destroy
has_many :procedures, through: :encounter_procedures
has_many :actuals, :dependent => :destroy
has_many :providers, through: :actuals
...
scope :by_updated_since, -> updated_at {
joins(:facility)
.joins(:physician)
.joins(:encounter_type)
.joins(:group)
.joins(:insurance)
.where("encounters.updated_at >= ? OR
facilities.updated_at >= ? OR
physicians.updated_at >= ? OR
encounter_types.updated_at >= ? OR
groups.updated_at >= ? OR
insurances.updated_at >= ?",
updated_at, updated_at, updated_at, updated_at, updated_at, updated_at)}
...
end
生成 SQL 的日志
app/controllers/api/v1/encounters_controller.rb:12:in `index'
Started GET "/api/v1/encounters?updated_since=2017-08-01" for 127.0.0.1 at 2017-08-10 11:55:01 -0500
Processing by Api::V1::EncountersController#index as JSON
Parameters: {"updated_since"=>"2017-08-01"}
Encounter Load (32.2ms) SELECT "encounters".* FROM "encounters" INNER JOIN "facilities" ON "facilities"."id" = "encounters"."facility_id" INNER JOIN "physicians" ON "physicians"."id" = "encounters"."physician_id" INNER JOIN "encounter_types" ON "encounter_types"."id" = "encounters"."encounter_type_id" INNER JOIN "groups" ON "groups"."id" = "encounters"."group_id" INNER JOIN "insurances" ON "insurances"."id" = "encounters"."insurance_id" WHERE (encounters.updated_at >= '2017-08-01' OR
facilities.updated_at >= '2017-08-01' OR
physicians.updated_at >= '2017-08-01' OR
encounter_types.updated_at >= '2017-08-01' OR
groups.updated_at >= '2017-08-01' OR
insurances.updated_at >= '2017-08-01')
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (0.12ms)
Completed 200 OK in 81ms (Views: 31.4ms | ActiveRecord: 32.2ms)
【问题讨论】:
-
你正在做很多连接!也许你应该在你的
belongs_to关系中考虑touch: true(apidock.com/rails/ActiveRecord/Persistence/touch) -
另外,这些连接关系是强制性的吗?例如,如果
Encounter记录没有(现有的)关联Insurance,则INNER JOIN将从列表中删除该Encounter记录。尝试使用includes而不是joins -
我认为它们是强制性的,因此如果关联模型最近更新(而不是 Encounter 记录本身),Encounter 记录仍会显示在结果中。
-
当我将“joins”更改为“includes”时出现错误--->“PG::UndefinedTable: ERROR: missing FROM-clause entry for table "facilities" LINE 2: facility.updated_at >= '2017-08-01' OR ^ : SELECT "encounters".* FROM "encounters" WHERE (encounters.updated_at >= '2017-08-01' OR facility.updated_at >= '2017-08-01' OR医师.updated_at >= '2017-08-01' 或遇到类型.updated_at >= '2017-08-01' 或 groups.updated_at >= '2017-08-01' 或 insurances.updated_at >= '2017-08-01 ')"
-
试试
includes(:facility, :physician, :encounter_type, :group, :insurance).references(:facility, :physician, :encounter_type, :group, :insurance).where(...)
标签: ruby-on-rails scope rails-activerecord ruby-on-rails-5