2013-09-02 22 views
10

Po prostu myśl w mojej głowie. jaka jest różnica następująceRuby on Rails before_filter vs initialized ruby ​​

before_filter

class ApplicationController < ActionController::Base 
    before_filter :foo 
    def foo 
    @mode = Model.new 
    end 
end 

rubin zainicjować

class ApplicationController < ActionController::Base 
    def initialize 
    foo 
    end 

    def foo 
    @mode = Model.new 
    end 
end 
  1. Czy praca metoda initialize Ruby jak oczekiwano w szynach?
  2. Jeśli tak, to czy możemy użyć funkcji initialize, aby zastosować filtr do wszystkich działań w kontrolerze?
+0

jesteś małpką łatającą coś, czego nie znasz, bez szacunku dla api. Przeciągnij palcami lub użyj before_filter – apneadiving

+0

Domyślam się, że Railsy buforują klasy w produkcji, które będą wykonywane dopiero po ponownym uruchomieniu preserver (lub dopóki gc nie usunie obiektu, ale jest to mało prawdopodobne w przypadku kontrolera aplikacji). Pamiętaj, że to tylko moja luźna myśl: –

+1

@MichaelSzyndel, otrzymasz świeży ApplicationController dla każdego żądania. – naomik

Odpowiedz

21

Dla każdego żądania, dostaniesz nową instancję ApplicationController, ale duży nie-nie jest to, że próbujesz zastąpić rdzenia zachowanie ActionController::Base#initialize bez wywoływania zachowanie rodzica.

ApplicationController < ActionController::Base 

    def initialize 
    super # this calls ActionController::Base initialize 
    init_foo 
    end 

    private 

    def init_foo 
    @foo = Foo.new 
    end 
end 

To nie jest idiomatyczne zachowanie Railsów. Dają ci before_filter z jakiegoś powodu; więc użyj go.

+0

funkcja callling w inicjalizacji + super, jest taka sama jak funkcja wywołania z 'before_filter'? – CuriousMind

+0

@GaurishSharma jest prawdopodobnie podobny, ale kolejność rzeczy na pewno ma znaczenie. Np. Czy nazywasz 'super' przed' init_foo' lub po?Jeśli nie masz głębokiego zrozumienia sposobu, w jaki skonfigurowano "ActionController :: Base", jest kilka małych pułapek, na które możesz się natknąć. 'before_filter' daje ci pożądane zachowanie i jest to" Rails Way "robienia rzeczy. Jeśli używasz Railsów, po prostu idź z przepływem, w przeciwnym razie możesz napotkać kłopoty. – naomik

3

Wierzę, że został on objęty w Practical Object-Oriented Design in Ruby przez Sandi Metz.

Załóżmy, że projektując klasę bazową dla innych programistów/użytkowników i chcemy, aby umożliwić im hak do różnych etapów postępowania (np inicjalizacji.) Ogólnie rzecz biorąc, istnieją dwa sposoby:

  1. Przerwij procedurę na małe metody i (w dokumentacji) przypomnij użytkownikom, aby używali super, gdy zastępują metodę.
  2. Uwzględniaj połączenia do różnych metod usuwania haczyków, które użytkownicy mogą zastąpić niestandardowymi funkcjami.

(wierzę, że są to odmiany wzoru Template Method.)

Drugi sposób wymaga więcej wysiłku ze strony użytkownika i mniej wysiłku dla swoich użytkowników.

W tym konkretnym przypadku before_filter zapewnia czystszy sposób dołączania wielu haków i zachęca do dzielenia haków na metody z jedną odpowiedzialnością o znaczących nazwach. Staje się to ważniejsze w aplikacjach, które korzystają z większego dziedziczenia kontrolerów.