2011-07-12 24 views
20

Có thể đặt lại bố cục mặc định từ trong phương thức before_filter trong Rails 3 không?Đường ray đặt bố cục từ bên trong phương thức before_filter

Tôi đã sau khi contacts_controller.rb tôi:

class ContactsController < ApplicationController 
    before_filter :admin_required, :only => [:index, :show] 
    def show 
    @contact = Contact.find(params[:id]) 
    respond_to do |format| 
     format.html # show.html.erb 
     format.xml { render :xml => @contact } 
    end 
    end 
    [...] 
end 

Và sau trong application_controller.rb tôi

class ApplicationController < ActionController::Base 
    layout 'usual_layout' 
    private 
    def admin_required 
    if !authorized?   # please, ignore it. this is not important 
     redirect_to[...] 
     return false 
    else 
     layout 'admin' [???] # this is where I would like to define a new layout 
     return true 
    end 
    end 
end 

Tôi biết tôi chỉ có thể đưa ...

layout 'admin', :only => [:index, :show] 

... ngay sau "before_filter" trong "ContactsController", nhưng, như tôi đã có một loạt các bộ điều khiển khác với nhiều hành động đúng cách được lọc như những người quản trị yêu cầu, nó sẽ được easer nhiều hơn nếu tôi chỉ có thể thiết lập lại bố trí từ "normal_layout" thành "admin" bên trong phương thức "admin_required".

BTW, bằng cách đặt ...

layout 'admin' 

... bên trong "admin_required" (như tôi đã cố gắng trong đoạn code trên), tôi nhận được một thông báo lỗi phương pháp xác định. Dường như nó chỉ hoạt động ngoài tầm kiểm soát, giống như tôi đã làm cho "normal_layout".

Xin cảm ơn trước.

Trả lời

68

Từ Rails guides, 2.2.13.2 Choosing Layouts at Runtime:

class ProductsController < ApplicationController 
    layout :products_layout 

    private 

    def products_layout 
    @current_user.special? ? "special" : "products" 
    end 
end 
+0

Đừng quên để chấp nhận câu trả lời đúng, nhờ – apneadiving

+0

Cảm ơn apneadiving, nhưng đây không phải là chính xác những gì tôi muốn nói. Tôi đã có một phương thức được thực hiện trước đúng trên một loạt các bộ điều khiển, lọc các hành động rất giống nhau nên được trả lại với bố cục đặc biệt này. Nhưng phương thức này được kích hoạt bởi lệnh before_filter. Tôi không muốn thay thế mỗi before_filter trên mỗi controller bằng một lệnh layout bây giờ trỏ tới một phương thức từ bên trong, tôi sẽ nhận được tên layout thích hợp - hoặc thêm vào nó. Tôi cần xác định bố trí đặc biệt từ bên trong cùng một phương thức đã được kích hoạt bởi lệnh before_filter. – guicassolato

+0

Vâng, tôi quyết định làm theo gợi ý của apneadiving. Phải mất một thời gian nhưng tôi đã thay thế mọi 'before_filter: admin_required,: only => [...]' bằng 'layout: admin_required,: only => [...]'. Nó hoạt động tốt. Cảm ơn. – guicassolato

18

Nếu vì một số lý do bạn không thể sửa đổi các điều khiển hiện có và/hoặc chỉ muốn làm điều này trong một trước khi lọc bạn có thể sử dụng self.class.layout :special đây là một ví dụ:

class ProductsController < ApplicationController 
    layout :products 
    before_filter :set_special_layout 

    private 

    def set_special_layout 
    self.class.layout :special if @current_user.special? 
    end 
end 

Nó chỉ là một cách khác để làm điều tương tự. Các tùy chọn khác giúp cho các lập trình viên hạnh phúc hơn !!

+11

Vấn đề lớn mà tôi gặp phải với phương thức này là bố cục được lưu trữ bởi Rails, và do đó có thể áp dụng ngay cả khi nó không được yêu cầu. Chủ đề an toàn hoặc một số như vậy. Sử dụng 'layout: set_layout' và' def set_layout', an toàn hơn nhiều :) – sevenseacat

2

Cách hiện đại để làm điều này là sử dụng một proc,

layout proc { |controller| user.logged_in? "layout1" : "layout2" } 
Các vấn đề liên quan