仅为某些 ActiveRecord 查询禁用 Rails STI
Disable Rails STI for certain ActiveRecord queries only
我可以为整个模型禁用 STI,但我只想在执行某些查询时禁用它。在 Rails 3.2 中一切正常,但我已经升级到 Rails 4.1.13 并且发生了一件打破查询的新事情。
我有一个名为 Person 的基础 class,其作用域相当复杂。
class Person < ActiveRecord::Base
include ActiveRecord::Sanitization
has_many :approvals, :dependent => :destroy
has_many :years, through: :approvals
scope :for_current_or_last_year, lambda {
joins(:approvals).merge(Approval.for_current_or_last_year) }
scope :for_current_or_last_year_latest_only, ->{
approvals_sql = for_current_or_last_year.select('person_id AS ap_person_id, MAX(year_id) AS max_year, year_id AS ap_year_id, status_name AS ap_status_name, active AS ap_active, approved AS ap_approved').group(:id).to_sql
approvals_sql = select("*").from("(#{approvals_sql}) AS ap, approvals AS ap2").where('ap2.person_id = ap.ap_person_id AND ap2.year_id = ap.max_year').to_sql
select("people.id, ap_approved, ap_year_id, ap_status_name, ap_active").
joins("JOIN (#{approvals_sql}) filtered_people ON people.id =
filtered_people.person_id").uniq
}
end
并继承 classes 称为 Member 和 Staff。唯一与此相关的事情我不得不注释掉以使我的测试通过Rails 4。这可能是问题所在,但在这种情况下取消注释并没有帮助。
class Member < Person
#has_many :approvals, :foreign_key => 'person_id', :dependent => :destroy, :class_name => "MemberApproval"
end
当我查询时出现问题Member.for_current_or_last_year_latest_only
我收到错误 unknown column 'people.type'
当我查看 SQL 时,我可以看到问题所在的行,但我不知道如何删除它或使其正常工作。
Member.for_current_or_last_year_latest_only.to_sql
结果。
SELECT DISTINCT people.id, ap_approved, ap_year_id, ap_status_name, ap_active
FROM `people`
JOIN (SELECT * FROM (SELECT person_id AS ap_person_id, MAX(year_id) AS max_year, year_id AS ap_year_id, status_name AS ap_status_name, active AS ap_active, approved AS ap_approved
FROM `people` INNER JOIN `approvals` ON `approvals`.`person_id` = `people`.`id`
WHERE `people`.`type` IN ('Member') AND ((`approvals`.`year_id` = 9 OR `approvals`.`year_id` = 8))
GROUP BY `people`.`id`) AS ap, approvals AS ap2
WHERE `people`.`type` IN ('Member') AND (ap2.person_id = ap.ap_person_id AND ap2.year_id = ap.max_year)) filtered_people ON people.id = filtered_people.person_id
WHERE `people`.`type` IN ('Member')
如果我从倒数第二个 WHERE
子句的开头删除 people.type IN ('Member') AND
,查询将成功运行。顺便说一句,那部分不在从旧的 Rails 3.2 代码生成的查询中,它上面的那个也不在(只有最后一个匹配 Rails 3.2 查询)。问题是,那部分是从我假设的 rails 单 Table 继承生成的,所以我不能只从查询中删除它。它不是唯一添加到原始查询中的地方,但这是唯一导致它中断的地方。
有没有人知道我如何才能仅对某些查询禁用 STI 或向我的查询中添加一些内容以使其正常工作?我尝试将 people.type
放入每个 SELECT
查询中以尝试使其可用但无济于事。
感谢您抽出宝贵时间查看此内容。
我显然使这比实际更难...我只需要将 unscoped
添加到两个 approval_sql
子查询的前面。感谢您帮助我的大脑换档。
我可以为整个模型禁用 STI,但我只想在执行某些查询时禁用它。在 Rails 3.2 中一切正常,但我已经升级到 Rails 4.1.13 并且发生了一件打破查询的新事情。
我有一个名为 Person 的基础 class,其作用域相当复杂。
class Person < ActiveRecord::Base
include ActiveRecord::Sanitization
has_many :approvals, :dependent => :destroy
has_many :years, through: :approvals
scope :for_current_or_last_year, lambda {
joins(:approvals).merge(Approval.for_current_or_last_year) }
scope :for_current_or_last_year_latest_only, ->{
approvals_sql = for_current_or_last_year.select('person_id AS ap_person_id, MAX(year_id) AS max_year, year_id AS ap_year_id, status_name AS ap_status_name, active AS ap_active, approved AS ap_approved').group(:id).to_sql
approvals_sql = select("*").from("(#{approvals_sql}) AS ap, approvals AS ap2").where('ap2.person_id = ap.ap_person_id AND ap2.year_id = ap.max_year').to_sql
select("people.id, ap_approved, ap_year_id, ap_status_name, ap_active").
joins("JOIN (#{approvals_sql}) filtered_people ON people.id =
filtered_people.person_id").uniq
}
end
并继承 classes 称为 Member 和 Staff。唯一与此相关的事情我不得不注释掉以使我的测试通过Rails 4。这可能是问题所在,但在这种情况下取消注释并没有帮助。
class Member < Person
#has_many :approvals, :foreign_key => 'person_id', :dependent => :destroy, :class_name => "MemberApproval"
end
当我查询时出现问题Member.for_current_or_last_year_latest_only
我收到错误 unknown column 'people.type'
当我查看 SQL 时,我可以看到问题所在的行,但我不知道如何删除它或使其正常工作。
Member.for_current_or_last_year_latest_only.to_sql
结果。
SELECT DISTINCT people.id, ap_approved, ap_year_id, ap_status_name, ap_active
FROM `people`
JOIN (SELECT * FROM (SELECT person_id AS ap_person_id, MAX(year_id) AS max_year, year_id AS ap_year_id, status_name AS ap_status_name, active AS ap_active, approved AS ap_approved
FROM `people` INNER JOIN `approvals` ON `approvals`.`person_id` = `people`.`id`
WHERE `people`.`type` IN ('Member') AND ((`approvals`.`year_id` = 9 OR `approvals`.`year_id` = 8))
GROUP BY `people`.`id`) AS ap, approvals AS ap2
WHERE `people`.`type` IN ('Member') AND (ap2.person_id = ap.ap_person_id AND ap2.year_id = ap.max_year)) filtered_people ON people.id = filtered_people.person_id
WHERE `people`.`type` IN ('Member')
如果我从倒数第二个 WHERE
子句的开头删除 people.type IN ('Member') AND
,查询将成功运行。顺便说一句,那部分不在从旧的 Rails 3.2 代码生成的查询中,它上面的那个也不在(只有最后一个匹配 Rails 3.2 查询)。问题是,那部分是从我假设的 rails 单 Table 继承生成的,所以我不能只从查询中删除它。它不是唯一添加到原始查询中的地方,但这是唯一导致它中断的地方。
有没有人知道我如何才能仅对某些查询禁用 STI 或向我的查询中添加一些内容以使其正常工作?我尝试将 people.type
放入每个 SELECT
查询中以尝试使其可用但无济于事。
感谢您抽出宝贵时间查看此内容。
我显然使这比实际更难...我只需要将 unscoped
添加到两个 approval_sql
子查询的前面。感谢您帮助我的大脑换档。