Мотивация
Мотивация состояла в том, что я хочу встроить сериализацию любой модели, которая была включена в цепочку отношений. То, что я сделал, работает на уровне отношений, но если я получу одну запись, сериализация не сможет воспользоваться тем, что я сделал.
Чего я достиг до сих пор
В основном я использую метод includes_values
класса ActiveRecord::Relation
, который просто сообщает мне, что было включено до сих пор. Т.е.
> Appointment.includes(:patient).includes(:slot).includes_values
=> [:patient, :slot]
Чтобы воспользоваться этим, я перезаписываю метод as_json
на уровне ActiveRecord::Relation
с помощью этого инициализатора:
# config/initializers/active_record_patches.rb
module ActiveRecord
class Relation
def as_json(**options)
super(options.merge(include: includes_values)) # I could precondition this behaviour with a config
end
end
end
Что он делает, так это добавьте для меня опцию include
в методе отношения as_json
.
Итак, старую цепочку:
Appointment.includes(:patient).includes(:slot).as_json(include: [:patient, :slot])
можно написать без последнего включения:
Appointment.includes(:patient).includes(:slot).as_json
с получением тех же результатов (модели Patient
и Slot
встроены в сгенерированный га sh).
ПРОБЛЕМА
Проблема в том, что поскольку метод includes_values
относится к классу ActiveRecord::Relation
, я не могу использовать его на уровне записи, чтобы узнать, был ли выполнен вызов includes
.
Итак в настоящее время, когда я получаю запись по таким запросам и вызываю as_json
для нее, я не получаю встроенные модели.
И настоящая проблема заключается в ответе:
Как узнать, какие модели включены в цепочку запросов, которые извлекли текущую запись, учитывая, что это произошло?
Если бы я мог ответить на этот вопрос, то я мог бы Я перезапишу метод as_json
в моих собственных моделях с помощью:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
extend Associations
def as_json(**options)
super(options.merge(include: included_models_in_the_query_that_retrieved_me_as_a_record))
end
end
Одна идея
Одна из моих идей - переписать includes
где-то (может быть в моем инициализаторе, перезаписывая непосредственно класс ActiveRecord::Relation
, или мой класс ApplicationRecord
). Но, оказавшись там, я не могу найти простой способ «запечатать» произвольную информацию в записях, созданных отношением.