2013-09-02 32 views
10

Chỉ là một suy nghĩ trong đầu tôi. sự khác biệt sauRuby on Rails before_filter vs ruby ​​khởi tạo

before_filter

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

ruby ​​khởi

class ApplicationController < ActionController::Base 
    def initialize 
    foo 
    end 

    def foo 
    @mode = Model.new 
    end 
end 
  1. Liệu khởi tạo công việc phương pháp của ruby ​​như mong đợi trong đường ray là gì?
  2. Nếu có, thì chúng ta có thể sử dụng khởi tạo tại chỗ một bộ lọc phải được áp dụng cho tất cả các hành động trong bộ điều khiển không?
+0

bạn đang khỉ vá cái gì đó bạn không biết, mà không tôn trọng api. Vượt qua các ngón tay của bạn hoặc sử dụng before_filter – apneadiving

+0

Tôi đoán, khi Rails lưu trữ các lớp trong sản xuất, nó sẽ chỉ được thực thi khi khởi động lại trình quản lý (hoặc cho đến khi gc loại bỏ đối tượng, nhưng điều này không có khả năng cho trình điều khiển ứng dụng). Tâm trí nó chỉ là suy nghĩ lỏng lẻo của tôi –

+1

@MichaelSzyndel, bạn sẽ nhận được một ApplicationController mới cho mỗi yêu cầu. – naomik

Trả lời

21

Đối với mỗi yêu cầu, bạn nhận được một trường hợp mới của ApplicationController, nhưng không lớn không có ở đây là bạn đang cố gắng để thay đổi hành vi cốt lõi của ActionController::Base#initialize mà không gọi hành vi cha mẹ.

ApplicationController < ActionController::Base 

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

    private 

    def init_foo 
    @foo = Foo.new 
    end 
end 

Đây không phải là hành vi Rủi ro thành ngữ. Họ cung cấp cho bạn before_filter vì một lý do; để sử dụng nó.

+0

vì vậy hàm callling trong khởi tạo + siêu, giống như chức năng gọi với 'before_filter'? – CuriousMind

+0

@GaurishSharma nó có thể tương tự, nhưng thứ tự của mọi thứ chắc chắn quan trọng. Ví dụ: bạn có gọi 'super' trước' init_foo' hay sau?Trừ khi bạn có một sự hiểu biết sâu sắc về cách 'ActionController :: Base' được thiết lập, có rất ít gotchas bạn có thể chạy vào. 'before_filter' cung cấp cho bạn hành vi mong muốn và đó là" Rails Way "của việc làm. Nếu bạn đang sử dụng Rails, chỉ cần đi với dòng chảy, nếu không bạn có thể gặp rắc rối. – naomik

3

Tôi tin rằng điều này đã được đề cập trong Practical Object-Oriented Design in Ruby bởi Sandi Metz.

Giả sử bạn đang thiết kế một lớp cơ sở cho các nhà phát triển/người dùng khác, và muốn cho phép họ để móc vào các bước khác nhau trong một thủ tục (ví dụ khởi tạo.) Nói chung, có hai cách:

  1. Chia nhỏ quy trình thành các phương thức nhỏ và (trong tài liệu hướng dẫn) nhắc người dùng sử dụng super bất cứ khi nào họ ghi đè phương thức.
  2. Bao gồm các cuộc gọi đến nhiều phương thức móc trống khác nhau mà người dùng có thể ghi đè bằng chức năng tùy chỉnh.

(Tôi tin rằng đây là những biến thể của mô hình Template Method.)

Cách thứ hai đòi hỏi nỗ lực nhiều hơn từ phía bạn và nỗ lực ít hơn cho người dùng của bạn.

Trong trường hợp cụ thể này, before_filter cung cấp cách gọn hơn để đính kèm nhiều móc và khuyến khích bạn chia móc thành các phương thức có trách nhiệm với tên có ý nghĩa. Điều này trở nên quan trọng hơn trong các ứng dụng sử dụng nhiều bộ điều khiển thừa kế.