2009-10-05 36 views
5

Tôi đang xây dựng CMS với các mô-đun khác nhau (blog, lịch, v.v.) bằng Rails 2.3. Mỗi mô-đun được xử lý bởi một bộ điều khiển khác nhau và hoạt động tốt.Định tuyến Rails động dựa trên cơ sở dữ liệu

Vấn đề duy nhất tôi có là với URL gốc. Tùy thuộc vào cấu hình do người dùng chọn, URL mặc định này sẽ hiển thị một mô-đun khác, tức là một bộ điều khiển khác, nhưng cách duy nhất tôi phải xác định bộ điều khiển chính xác là kiểm tra cơ sở dữ liệu cho mô-đun "mặc định" nào được hiển thị.

Hiện tại tôi đang sử dụng bộ điều khiển "gốc" cụ thể để kiểm tra cơ sở dữ liệu và chuyển hướng tới bộ điều khiển chính xác. Tuy nhiên tôi muốn URL không được thay đổi, có nghĩa là tôi muốn gọi bộ điều khiển chính xác từ cùng một yêu cầu.

Tôi đã thử sử dụng Rails Metal để tìm thông tin này và gọi bộ điều khiển theo cách thủ công nhưng tôi nghĩ tôi có thể đang phát minh lại bánh xe (xác định đường dẫn yêu cầu để chọn bộ điều khiển, quản lý phiên, v.v.).

Bất kỳ ý tưởng nào? Cảm ơn rất nhiều trước!

Trả lời

5

Vấn đề này có thể được giải quyết với một số Kệ middleware:

Mã này trong lib/root_rewriter.rb:

module DefV 
    class RootRewriter 
    def initialize(app) 
     @app = app 
    end 

    def call(env) 
     if env['REQUEST_URI'] == '/' # Root is requested! 
     env['REQUEST_URI'] = Page.find_by_root(true).uri # for example /blog/ 
     end 

     @app.call(env) 
    end 
    end 
end 

Sau đó, trong config/environment.rb của bạn ở phía dưới

require 'root_rewriter' 
ActionController::Dispatcher.middleware.insert_after ActiveRecord::QueryCache, DefV::RootRewriter 

middleware này sẽ kiểm tra nếu trang được yêu cầu (REQUEST_URI) là '/' và sau đó thực hiện tìm kiếm đường dẫn thực tế (Thực hiện điều này tùy thuộc vào bạn ;-)). Bạn có thể làm tốt việc lưu vào bộ nhớ đệm thông tin này ở đâu đó (Cache.fetch('root_path') { Page.find... })

Có một số vấn đề với việc kiểm tra REQUEST_URI, vì không phải tất cả máy chủ web đều vượt qua chính xác. Đối với các chi tiết thực hiện toàn bộ trong Rails thấy http://api.rubyonrails.org/classes/ActionController/Request.html#M000720 (Nhấp vào "Xem nguồn")

+0

Vâng, công trình này! Đây là nhiều hơn hoặc ít hơn những gì tôi đã cố gắng để làm, nhưng không thành công cho đến bây giờ. Cảm ơn Jan! –

2

Trong Rails 3.2 này là những gì tôi đã đưa ra (vẫn còn là một trung gian):

class RootRewriter 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    if ['', '/'].include? env['PATH_INFO'] 
     default_thing = # Do your model lookup here to determine your default item 
     env['PATH_INFO'] = # Assemble your new 'internal' path here (a string) 
     # I found useful methods to be: ActiveModel::Naming.route_key() and to_param 
    end 

    @app.call(env) 
    end 
end 

này cho Rails rằng con đường là khác với những gì được yêu cầu (đường dẫn gốc) để tham chiếu đến link_to_unless_current và những thứ tương tự vẫn hoạt động tốt.

Nạp middleware trong như vậy trong một initialiser:

MyApp::Application.config.middleware.use RootRewriter 
Các vấn đề liên quan