Как ActiveRecord :: Relation добавляется в модели Rails и почему каждая модель имеет отдельный класс Relation? - PullRequest
1 голос
/ 22 марта 2019

Предположим, у меня есть модель Rails: class Project < ActiveRecord::Base

В консоли Rails:

> Project.all
=> #<ActiveRecord::Relation []>

Это кажется разумным.Тем не менее,

> Project.all.class
=> Project::ActiveRecord_Relation

Что такое Project::ActiveRecord_Relation?В частности,

  • Как он "добавился" (в пространство имен) к моему классу модели?
  • Как он правильно отвечает на is_a??Project.all.is_a?(ActiveRecord::Relation) возвращает true (что ожидается), но действительно ли Project::ActiveRecord_Relation является экземпляром ActiveRecord::Relation или это что-то еще?
  • Почему это происходит?Почему Project.all не возвращает ActiveRecord::Relation, а не Project::ActiveRecord_Relation?

(Это в контексте Rails 5.1, если оно изменилось в более старых или более новых версиях.)

(я открыт для редактирования заголовков, если кто-то может придумать лучший заголовок для этого вопроса)

Ответы [ 2 ]

2 голосов
/ 23 марта 2019

На самом деле вы задаете два вопроса:

  1. Как это работает?
  2. Почему это так?(Зачем?)

@arieljuod уже дал вам некоторые объяснения и ссылку.

Однако, второй вопрос все еще остается без ответа.

Есть еще одинСуществует похожий вопрос, который, я надеюсь, поможет вам найти все ответы:

Как объект ActiveRecord :: Relation может вызывать методы класса

Похоже на два вопроса (по ссылке и вашей) ответьте друг другу)

Посмотрите на ответ @nikita-shilnikov.Удачи в расследовании!

2 голосов
/ 22 марта 2019

Проверьте эту строку кода из ActiveRecord.

https://github.com/rails/rails/blob/f40860800c231ecd1daef6cf6b5a8a8eda76478d/activerecord/lib/active_record/relation/delegation.rb#L23

mangled_name = klass.name.gsub("::", "_")

Итак, на ваши вопросы:

  • он добавляется на основе activerecord при расширении модуля делегирования https://github.com/rails/rails/blob/f40860800c231ecd1daef6cf6b5a8a8eda76478d/activerecord/lib/active_record/base.rb#L290

  • на самом деле это тот же класс, просто что-то вроде псевдонима (на самом деле это не псевдоним, а константа с классом в качестве значения)

  • класс на самом деле ActiveRecord::Relation, просто имя было изменено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...