【发布时间】:2018-06-06 17:38:25
【问题描述】:
我的大多数模型共享两个范围。他们有直接引用模型表名的原始 SQL,这与 Arel 不能很好地配合:
class ApplicationRecord < ActiveRecord::Base
valid = lambda do |positive = true|
if %w[validForBegin validForEnd].all? { |c| base_class.column_names.include?(c) }
condition = "NOW() BETWEEN #{base_class.table_name}.validForBegin AND #{base_class.table_name}.validForEnd"
condition = "!(#{condition})" unless positive
where(condition)
end
end
scope :valid, valid
scope :invalid, -> { valid(false) }
end
# Sample usage
class Party < ApplicationRecord
has_one :name,
-> { valid },
class_name: 'PartyName',
foreign_key: :partyId,
has_many :expired_names,
-> { invalid },
class_name: 'PartyName',
foreign_key: :partyId,
end
由于我的范围直接指向模型的table_name,我不能同时加入这两个关联:
Party.joins(:name, :expired_names).first
# Produces this sequel statement
SELECT `party`.*
FROM `party`
INNER JOIN `party_name` ON `party_name`.`partyId` = `party`.`id`
AND (NOW() BETWEEN party_name.validForBegin AND party_name.validForEnd)
INNER JOIN `party_name` `expired_names_party` ON `expired_names_party`.`partyId` = `party`.`id`
AND (!(NOW() BETWEEN party_name.validForBegin AND party_name.validForEnd))
ORDER BY `party`.`id` ASC LIMIT 1
请注意,连接上的两个“AND”条件均指表party_name。第二个应该引用expired_names_party,动态生成的表别名。对于更复杂的 Rails 查询,其中 Arel 为每个表分配别名,两个连接都将失败。
我的作用域是否可以使用 Arel 在执行时分配给它的别名?
【问题讨论】:
标签: ruby-on-rails associations