Jak stworzyć i używać modułu używając Ruby on Rails 3?

90

Używam Ruby on Rails 3 i chciałbym przenieść niestandardowy i współdzielony kod do modułu.

  1. Jakiej składni powinienem użyć do napisania kodu modułu?
  2. W którym folderze mojej aplikacji mam umieścić plik modułu?
  3. Jak mam dołączyć ten moduł do jednej lub więcej klas kontrolerów?
  4. Jakie inne czynności muszę wykonać, aby użyć modułu niestandardowego w dowolnym miejscu w mojej aplikacji?
  5. Jak mogę wywołać metody w module z mojej aplikacji?

Z góry dziękuję.

user502052
źródło
2
Bardzo dobrze! Potrzebowałam tego.
Arup Rakshit,

Odpowiedzi:

116

Aby 1. Utworzyć / otworzyć moduł, mówiąc po prostu:

module MyModule
  def first_module_method
  end
end

Do 2. libfolderu. Jeśli chcesz uporządkować swoje moduły w libfolderze, możesz je same umieścić w modułach. Na przykład, jeśli chcesz mieć podfolder, super_modulesTwoje moduły będą zdefiniowane w następujący sposób:

module SuperModules
  module MyModule
    def first_module_method
    end
  end
end

Do 3./5. Włączając moduł do klasy, możesz po prostu wywołać metody modułów tak, jakby były zdefiniowane w klasie:

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

Do 4. Najpierw upewnij się, że Twój moduł jest naprawdę potrzebny w każdej klasie Twojej aplikacji. Jeśli nie jest, sensowne jest umieszczanie go tylko tam, gdzie jest to potrzebne, aby nie nadużywać klas, które i tak go nie potrzebują. Jeśli naprawdę chcesz, aby moduł był wszędzie, spójrz na hierarchię klas swoich klas w aplikacji. Czy chcesz mieć moduł we wszystkich modelach? Możesz otworzyć ActiveRecord :: Base i dodać tam swój moduł.

Stephan
źródło
2
Czy w celu organizowania plików mogę utworzyć podfolder w folderze „lib”? Jeśli tak, jakie zmiany?
user502052
2
@ user502052 Zaktualizowałem odpowiedź do punktu 2, aby odpowiedzieć na to pytanie.
Stephan,
3
Wiele rzeczy jest tutaj niejasnych. Jakie nazwy plików nadać? Jak wywołać metody, gdy nie zawierają całego modułu? Nie mogę uwierzyć, że jest tak wiele głosów za, ponieważ nadal nie wiem, jak używać modułu na końcu.
Augustin Riedinger
5
Po utworzeniu modułu jak wyżej, włączając go w libfolderze, ważna uwaga jest umożliwienie Rails3 odkomentować linię config\application.rbdla config.autoload_paths- odczytać np stackoverflow.com/questions/1073076/rails-lib-modules-and ... Uwaga należy również uważać, aby użyć nazwy pliku dla swojego modułu, która pasuje do samej nazwy modułu. Więc jeśli zapiszesz to w lib/test/my_module.rb, musisz include Test::MyModule- aby uzyskać więcej informacji, zobacz stackoverflow.com/questions/4073856/rails-3-autoload
sameers
6
Właśnie znalazłem tę swoją starą odpowiedź. :( Chcę głosować negatywnie. Nie umieszczaj niczego w bibliotece! Umieść swój kod (w tym dodatkowe moduły) w, app/modelsjeśli kod wymaga dostępu do innych modeli. Jeśli Twój kod jest naprawdę „biblioteką” i może istnieć samodzielnie, ja zasugeruj sprzedanie klejnotu. Przykłady można znaleźć na github.com/shageman/the_next_big_thing
Stephan
3

A> 1. Możesz użyć tej samej składni, co w przypadku każdej innej klasy ruby. Na przykład definiuję moduł VehicleClassifer, który będzie używał metody classify_vehicle do klasyfikowania pojazdu na podstawie liczby kół, które otrzyma jako dane wejściowe.

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

A> 2. Moduły są zwykle przechowywane w folderze / lib.

pytania 3,4,5 mają mniej więcej taką samą odpowiedź. możesz użyć

class SomeController < ApplicationController
  include VehicleClassfier

  def index 
    classify_vehicle(4)  
  end
end

w klasie, w której używasz modułu, będziesz mieć dostęp do wszystkich metod modułu.

Ponadto, jeśli potrzebujesz użyć modułu w swojej aplikacji, możesz dołączyć go do kontrolera aplikacji.

Shreyas
źródło
2
Próbowałem tego i otrzymałem niezdefiniowany błąd metody. Masz pojęcie, co robię źle?
Tony
Czy na pewno Twój moduł jest dostępny? stackoverflow.com/questions/6604272/ ... może ci pomoże?
Shreyas
1
@Tony - Może być konieczne ponowne uruchomienie serwera - nawet w trybie deweloperskim, aby metody modułu były dostępne. Za każdym razem, gdy zmieniasz kod w swoim module, musisz ponownie uruchomić serwer. Na przykład, jeśli wystąpi błąd, lub wystąpi błąd w starym kodzie, ale podświetl nowy kod w tym wierszu w komunikacie o błędzie - bardzo mylące.
JosephK,
Masz pomysł, jak włączyć i używać tych niestandardowych modułów w środku ApplicationHelper?
WM