У меня есть две области, которые используются большинством моих моделей.У них есть сырой 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
Обратите внимание, что оба условия 'И' для объединений относятся к таблице party_name
.Второй должен вместо этого ссылаться на expired_names_party
, динамически генерируемый псевдоним таблицы.Для более сложных запросов Rails, когда Arel назначает псевдоним для КАЖДОЙ таблицы, оба соединения завершатся неудачно.
Возможно ли, чтобы моя область использовала псевдоним, назначенный ей Arel во время выполнения ?