66 votos

¿Cómo se relacionan require, require_dependency y la recarga de constantes en Rails?

¿Cómo se require y require_dependency ¿diferente?
¿Cómo puede require_dependency recargar automáticamente las clases en desarrollo, pero require ¿No?

He indagado en la ActiveSupport::Dependencies y el código dispatcher.rb. Lo que he visto en require_dependency es que básicamente añade las constantes a un código autoloaded_constants Array. Pero se borra en clear_application dentro del despachador después de cada solicitud.

¿Puede alguien darme una explicación clara o indicarme algunos recursos que me ayuden?

127voto

MDaubs Puntos 1804

require (y su primo load ) son métodos básicos de Ruby. require_dependency es un método que ayuda a Rails a manejar el problema de la gestión de dependencias. En pocas palabras, permite a Rails recargar las clases en modo de desarrollo para que no tengamos que reiniciar el servidor cada vez que hagamos un cambio en el código. El framework Rails require_dependency tu código para que pueda rastrearlo y recargarlo cuando se realicen cambios. El Ruby estándar require no lo hace. Como desarrollador de aplicaciones (o plugins/motores) no deberías tener que preocuparte por require_dependency ya que esto es puramente interno de Rails.

La magia del proceso de carga de clases Rails está en el módulo ActiveSupport::Dependencies. Este código amplía el comportamiento predeterminado de Ruby para permitir que el código de la aplicación Rails cargue automáticamente los módulos (incluidas las clases que heredan de Module) utilizando las convenciones de Rails sobre rutas y nombres de archivos. Esto elimina la necesidad de que el programador ensucie su código con require como en una aplicación Ruby normal.

Dicho de otro modo, esto le permite definir class Admin::User dentro del archivo app/models/admin/user.rb y que Rails sepa de qué estamos hablando cuando llamemos a Admin::User.new desde otra parte de la aplicación, como un controlador. Sin ActiveSupport::Dependencies implicado tendría que manualmente require todo lo que necesitabas.

Si vienes de un lenguaje de tipado estático como C#, Java, etc. esto puede sorprenderte: El código Rails no se carga hasta que se necesita. Por ejemplo, un User no está definida y user.rb no se carga hasta DESPUÉS de intentar llamar a User.whatever_method_here . Rails evita que Ruby se queje de esa constante que falta, carga código para User y luego permite que Ruby continúe normalmente.

Aunque no puedo hablar por su necesidad específica, me sorprendería mucho si usted realmente necesita para utilizar el require_dependency desde un plugin o motor. Si sigues las convenciones de Rails tampoco deberías tener que modificar $LOAD_PATH a mano. Esto no es "la manera Rails".

En el mundo de Ruby y también de Rails la simplicidad y la claridad son fundamentales. Si todo lo que quieres hacer es escribir un plugin o un motor y ya estás buceando en las profundidades de los aspectos internos, entonces puedes considerar enfocar tu problema desde un ángulo diferente. Mi instinto me dice que puede que estés intentando hacer algo innecesariamente complicado. Pero, de nuevo, ¡no tengo ni idea de lo que estás haciendo exactamente! :)

22voto

Kris Puntos 3781

require_dependency es útil en un motor cuando quieres volver a abrir una clase que no está definida en tu motor (por ejemplo en otro motor o aplicación Rails) y hacer que se recargue. En cuyo caso funciona algo como esto:

# app/controllers/my_engine/documents_controller.rb
require_dependency MyEngine::Engine.root.join('app', 'controllers', 'my_engine', 'documents_controller').to_s

module MyEngine
  class DocumentsController
    def show
      render :text => 'different'
    end
  end
end

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X