¿Cómo crear y usar un módulo usando Ruby on Rails 3?

90

Estoy usando Ruby on Rails 3 y me gustaría mover un código personalizado y compartido en un módulo.

  1. ¿Qué sintaxis debo utilizar para escribir el código del módulo?
  2. ¿En qué carpeta de mi aplicación tengo que colocar el archivo del módulo?
  3. ¿Cómo tengo que incluir ese módulo en una o más clases de controlador?
  4. ¿Qué otra acción, si corresponde, tengo que usar el módulo personalizado en cualquier lugar de mi aplicación?
  5. ¿Cómo puedo llamar a métodos en el módulo desde mi aplicación?

Gracias por adelantado.

user502052
fuente
2
¡Muy bien! Lo necesitaba.
Arup Rakshit

Respuestas:

115

Para 1. Un módulo se crea / abre simplemente diciendo:

module MyModule
  def first_module_method
  end
end

Para 2. La libcarpeta. Si desea organizar sus módulos en la libcarpeta, puede ponerlos en módulos. Por ejemplo, si quisiera una subcarpeta, super_modulessus módulos se definirían de la siguiente manera:

module SuperModules
  module MyModule
    def first_module_method
    end
  end
end

Hasta el 3./5. Al incluir el módulo en una clase, simplemente puede llamar a los métodos de los módulos como si estuvieran definidos dentro de la clase:

class MyClass
  include MyModule
  def some_method
    first_module_method #calls module method
  end
end

Para 4. Primero, asegúrese de que su módulo sea realmente necesario en cada clase de su aplicación. Si no es así, tiene sentido incluirlo solo donde sea necesario para no inflar las clases que no lo necesitan de todos modos. Si realmente desea que el módulo esté en todas partes, incluya un vistazo a la jerarquía de clases de sus clases en la aplicación. ¿Quieres el módulo en todos los modelos? Puede abrir ActiveRecord :: Base y agregar su módulo allí.

Stephan
fuente
2
Para organizar archivos, ¿puedo crear una subcarpeta en la carpeta 'lib'? Si es así, ¿qué cambia?
user502052
2
@ user502052 He actualizado la respuesta al punto 2 para responder esa pregunta.
Stephan
3
Muchas cosas no están claras aquí. ¿Qué nombres de archivo dar? ¿Cómo llamar a los métodos cuando no se incluye todo el módulo? No puedo creer que haya tantos votos positivos ya que todavía no sé cómo usar un módulo al final.
Augustin Riedinger
5
Una vez que crea un módulo como el anterior incluyéndolo en la libcarpeta, una nota importante es permitir que Rails3 descomente la línea config\application.rbpara config.autoload_paths: lea, por ejemplo, stackoverflow.com/questions/1073076/rails-lib-modules- y ... Nota también que debe tener cuidado de usar un nombre de archivo para su módulo que coincida con el nombre del módulo en sí. Entonces, si lo guarda lib/test/my_module.rb, debe hacerlo include Test::MyModule; para obtener más detalles, consulte stackoverflow.com/questions/4073856/rails-3-autoload
sameers
6
Acabo de encontrar esta vieja respuesta mía. :( Quiero votar en contra. ¡No pongas nada en lib! Pon tu código (incluidos los módulos adicionales) en app/modelssi el código necesita acceso a otros modelos. Si tu código es realmente una 'biblioteca' y puede existir por sí solo, sugiera vender una gema. Para ver ejemplos, consulte github.com/shageman/the_next_big_thing
Stephan
3

A> 1. Puede utilizar la misma sintaxis que cualquier otra clase de ruby. Por ejemplo, estoy definiendo un módulo VehicleClassifer que utilizará el método classify_vehicle para clasificar un vehículo en función del número de ruedas que recibe como entrada.

module VehicleClassifer
  def classify_vehicle(number_of_wheels)
    VehicleType.where("number_of_wheels = ?", number_of_wheels)
  end
end

A> 2. Los módulos generalmente se almacenan en la carpeta / lib.

las preguntas 3, 4, 5 tienen más o menos la misma respuesta. puedes usar

class SomeController < ApplicationController
  include VehicleClassfier

  def index 
    classify_vehicle(4)  
  end
end

en la clase que está utilizando el módulo y tendrá acceso a todos los métodos del módulo.

Además, en caso de que necesite utilizar un módulo en su aplicación, puede incluirlo en el controlador de su aplicación.

Shreyas
fuente
2
Intenté esto y obtuve un error de método indefinido. ¿Alguna idea de qué estoy haciendo mal?
Tony
¿Está seguro de que se puede acceder a su módulo? stackoverflow.com/questions/6604272/… ¿ tal vez te ayude?
Shreyas
1
@Tony: es posible que deba reiniciar su servidor, incluso en modo dev, para que los métodos del módulo estén disponibles. Y cada vez que cambie el código en su módulo, debe reiniciar el servidor nuevamente. Por ejemplo, si hay un error, o se producirá un error en el código anterior, pero resalte el nuevo código en esa línea en el mensaje de error, muy confuso.
JosephK
¿Alguna idea de cómo incluir y utilizar esos módulos personalizados en el interior ApplicationHelper?
WM