2008-09-24 13 views
77

Mam pewne metody kontrolerów, którymi chciałbym się podzielić. Jaka jest najlepsza praktyka w robieniu tego w rubinach na szynach? Czy powinienem utworzyć klasę abstrakcyjną, którą rozszerzają moje kontrolery, czy też powinienem utworzyć moduł i dodać go do każdego kontrolera? Poniżej przedstawiono metody kontrolerów, które chcę udostępnić:Najlepsze metody ponownego użycia kodu między kontrolerami w Ruby on Rails

def driving_directions 
    @address_to = params[:address_to] 
    @address_from = params[:address_from] 
    @map_center = params[:map_center_start] 

    # if we were not given a center point to start our map on 
    # let's create one. 
    if [email protected]_center && @address_to 
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_to).ll 
    elsif [email protected]_center && @address_from 
    @map_center = GeoKit::Geocoders::MultiGeocoder.geocode(@address_from).ll 
    end 
end 

def printer_friendly 
    starting_point = params[:starting_point].split(',').collect{|e|e.to_f} 
    ne = params[:ne].split(',').collect{|e|e.to_f} 
    sw = params[:sw].split(',').collect{|e|e.to_f} 
    size = params[:size].split(',').collect{|e|e.to_f} 
    address = params[:address] 

    @markers = retrieve_points(ne,sw,size,false) 
    @map = initialize_map([[sw[0],sw[1]],[ne[0],ne[1]]],[starting_point[0],starting_point[1]],false,@markers,true) 
    @address_string = address 
end 
+1

Czy istnieje szczególny powód, dla którego nie należy używać pliku application.rb w tym przypadku? –

+4

Tylko, że niektóre kontrolery będą używać tego kodu, ale nie wszystkie. –

Odpowiedz

110

Moim zdaniem zastosowanie normalne zasady projektowania OO:

  • Jeśli kod jest naprawdę zestaw narzędzi, które nie potrzebują dostępu do obiektu stanu, chciałbym rozważyć umieszczenie go w module nazywać osobno. Na przykład, jeśli kod jest wszystkim narzędziem mapowania, utwórz moduł Maps i uzyskaj dostęp do metod takich jak: Maps::driving_directions.
  • Jeśli kod wymaga podania stanu i jest używany lub może być użyty w każdym kontrolerze, należy umieścić kod w aplikacji ApplicationController.
  • Jeśli kod wymaga stanu i jest używany w podzbiorze wszystkich kontrolerów, które są ściśle i logicznie powiązane (tj. Wszystko o mapach), należy utworzyć klasę podstawową (class MapController < ApplicationController) i umieścić tam wspólny kod.
  • Jeśli kod wymaga stanu i jest używany w podzbiorze wszystkich kontrolerów, które nie są bardzo blisko spokrewnione, umieść go w module i dołącz do niezbędnych kontrolerów.

W twoim przypadku metody wymagają stanu (params), więc wybór zależy od logicznej relacji między kontrolerami, którzy jej potrzebują. Ponadto:

również:

  • Stosować partials, jeśli to możliwe do wielokrotnego kodu i każdym miejscu we wspólnym katalogu „partials” czy to poprzez określonej ścieżce.
  • Trzymaj się podejścia REST, jeśli to możliwe (w przypadku metod), a jeśli tworzysz wiele metod innych niż REST, rozważ wyodrębnienie ich do własnego kontrolera.
15

Właściwie uważam, że moduł jest najlepszym sposobem na udostępnianie kodu wśród kontrolerów. Pomocnicy są dobrzy, jeśli chcesz udostępniać kod między widokami. Pomocnicy są w zasadzie gloryfikowanymi modułami, więc jeśli nie potrzebujesz dostępu na poziomie widoku, sugeruję umieszczenie modułu w twoim folderze lib.

Po utworzeniu modułu, będziesz musiał użyć instrukcji include, aby dołączyć ją do pożądanych kontrolerów.

http://www.rubyist.net/~slagell/ruby/modules.html

1

zgadzam się z podejściem modułu. Utwórz oddzielny plik Ruby w katalogu lib i umieść moduł w nowym pliku.

Najbardziej oczywistym sposobem byłoby dodanie metod do aplikacji ApplicationController, ale jestem pewien, że już to wiesz.

0

Inna możliwość:

Jeśli wspólny kod musi stan i chcesz podzielić się zachowań wśród kontrolerów, można umieścić go w zwykły starej klasy ruby ​​w obu swojej model lub lib katalogu. Pamiętaj, że klasy model nie muszą być trwałe, nawet jeśli wszystkie klasy ActiveRecord są trwałe. Innymi słowy, dopuszczalne są przejściowe klasy model.

1

Jeśli chcesz udostępniać kody między kontrolerem i pomocnikami, powinieneś spróbować utworzyć moduł w bibliotece. Możesz użyć @template i @controller, aby uzyskać dostęp do metody również w kontrolerze i pomocniku. Sprawdź to po więcej szczegółów http://www.shanison.com/?p=305

29

Znam to pytanie zostało zadane 6 lat temu. Chciałbym tylko podkreślić, że w Rails 4 pojawiły się teraz obawy kontrolerów, które są bardziej nieszablonowym rozwiązaniem.

0

Odkryłem, że jednym skutecznym sposobem na udostępnienie identycznego kodu w kontrolerach jest posiadanie jednego kontrolera dziedziczącego po drugim (gdzie kod się znajduje). Użyłem tego podejścia, aby udostępnić identyczne metody zdefiniowane w moich kontrolerach za pomocą innego zestawu kontrolerów nazwanych.

+1

Używanie dziedziczenia do udostępniania kodu jest traktowane jako zapach kodu. Powinieneś tego unikać. Zobacz http://programmers.stackexchange.com/a/12446. Zamiast tego użyj modułów, obaw, a nawet [obiektu usług] (https://netguru.co/blog/service-objects-in-rails-will-help). – Mio