13

Tôi đang ở Rails 2.3.5 và tôi có vấn đề này:Tại sao Rails before_filter được gọi hai lần khi bộ điều khiển được phân lớp?

class BaseController < ApplicationController 
    before_filter :foo, :only => [:index] 
end 

class ChildController < BaseController 
    before_filter :foo, :only => [:index, :show, :other, :actions] 
end 

Vấn đề là trên ChildController thì: foo trước khi lọc được gọi hai lần.

Tôi đã thử một số cách giải quyết xung quanh vấn đề này. Nếu tôi không bao gồm hành động :index ở trẻ em, nó sẽ không bao giờ được gọi cho hành động đó.

Giải pháp tôi thấy công trình, nhưng tôi nghĩ rằng nó rất rất xấu xí

skip_before_filter :foo 
before_filter :foo, :only => [:index, :show, :other, :actions] 

Có cách nào tốt hơn để giải quyết vấn đề này?

Trả lời

15

"Hành vi này là do thiết kế".

Hướng dẫn Rails trên bộ điều khiển nói:

"Các bộ lọc được thừa hưởng, vì vậy nếu bạn thiết lập một bộ lọc trên ApplicationController, nó sẽ được chạy trên mọi bộ điều khiển trong ứng dụng của bạn"

Điều này giải thích hành vi bạn đang thấy. Nó cũng gợi ý chính xác giải pháp bạn đề xuất (sử dụng skip_before_filter) để xác định bộ lọc nào sẽ hoặc sẽ không được chạy cho một bộ điều khiển và/hoặc phương thức cụ thể.

Vì vậy, xấu xí hay không, có vẻ như giải pháp bạn tìm thấy là thực tiễn phổ biến và được chấp thuận.

http://guides.rubyonrails.org/action_controller_overview.html#filters

3

Nếu bạn không muốn sử dụng skip_before_filter bạn luôn có thể bỏ qua index hành động trong ChildController:

class ChildController < BaseController 
    before_filter :foo, :only => [:show, :other, :actions] 
end 

Nhưng điều này có thể trở thành một vấn đề nếu bạn thay đổi hành vi trong BaseController và xóa bộ lọc khỏi hành động index. Sau đó, nó sẽ không bao giờ được gọi là như vậy bằng cách sử dụng skip_before_filter có thể là một ý tưởng tốt hơn.

Các vấn đề liên quan