Как реализуется ruby ​​на рельсах has_many (и аналогичных)? - PullRequest
5 голосов
/ 26 февраля 2012

Я анализирую исходный код rails, потому что мне хотелось бы понять внутреннюю работу has_many и подобных конструкций.

До сих пор я был в состоянии найти, где реализован метод ( ссылка на github ): он находится в модуле ActiveRecord :: Associations

def has_many(name, options = {}, &extension)
  Builder::HasMany.build(self, name, options, &extension)
end

На этом один конец ( ссылка на github ) заканчивается в классе ActiveRecord :: Associations:: Builder :: CollectionAssociation as

def self.build(model, name, options, &extension)
  new(model, name, options, &extension).build
end

На этом мои навыки по рубину заканчиваются, и я не смог их отследить дальше и найти, где реализовано «новое» и что оно делает.

Можеткто-то указывает мне правильное направление и, возможно, комментирует, что происходит под капотом?

Ответы [ 3 ]

4 голосов
/ 26 февраля 2012

По существу, new определяется следующим образом:

class Class
  def new(*args, &block)
    obj = allocate

    obj.initialize(*args, &block)
    # *actually* obj.send(:initialize, *args, &block) since initialize is private

    obj
  end
end

allocate определяется следующим образом:

class Class
  def allocate
    # magic stuff for creating an empty object which cannot be expressed in Ruby:

    new_obj = Deep::Within::VM.__somehow_magically_allocate_memory__!

    new_obj.__class__ = self

    new_obj
  end
end
1 голос
/ 26 февраля 2012

Чтобы расширить ответ @ Baldrick, который является правильным, new определен в Class как метод класса и метод экземпляра и, следовательно, доступен для всех классов.

То, что делает new, вызывает allocate и initialize (при условии, что метод initialize был определен).

1 голос
/ 26 февраля 2012

new вызывает конструктор текущего класса.Конструктор - это метод initialize, который определяется сразу после self.build метода в классе CollectionAssociation.Это чистый рубин ( ruby ​​guide )

...