Điều bạn đang cố gắng làm là khá khó khăn. Như đã được đề cập các tuyến đường công cụ được tải sau khi các tuyến ứng dụng và ghi đè hành vi này có thể có vấn đề. Tôi có thể nghĩ ra một vài điều mà bạn có thể thử.
Sử dụng Một Initializer Sau Routing Paths Initializer
Có một initializer trong engine.rb
bên trong nguồn đường ray, một cách để thực hiện những gì bạn đang sau là cố gắng để móc vào các chức năng mà nó đối diện. Initializer trông như thế này theo mặc định:
initializer :add_routing_paths do |app|
paths.config.routes.to_a.each do |route|
app.routes_reloader.paths.unshift(route) if File.exists?(route)
end
end
Về cơ bản, điều này sẽ mất các đường dẫn cho tất cả các tập tin tuyến đường Rails biết về và cố gắng và thêm chúng vào các tuyến đường reloader (điều mà reloades nộp tuyến đường của bạn automagically cho bạn nếu nó được thay đổi). Bạn có thể định nghĩa một initializer khác được thực hiện ngay sau cái này, sau đó bạn sẽ kiểm tra các đường dẫn được lưu trữ trong reloader routes, kéo ra đường dẫn thuộc về engine của bạn, loại bỏ nó khỏi mảng path và chèn nó trở lại, nhưng ở cuối của mảng đường dẫn. Vì vậy, trong config/application.rb
của bạn:
class Application < Rails::Application
initializer :munge_routing_paths, :after => :add_routing_paths do |app|
engine_routes_path = app.routes_reloader.paths.select{|path| path =~ /<regex that matches path to my engine>/}.first
app.routes_reloader.paths.delete(engine_routes_path)
app.routes_reloader.paths << engine_routes_path
end
end
này có thể hoặc không thể làm việc, một trong hai cách tôi không thực sự khuyên bạn nên nó, nó không phải là đặc biệt thanh lịch (ví dụ: hack xấu xí chơi với ruột của đường ray).
Sử dụng Rails 3.1
này có thể không là một lựa chọn, nhưng nếu nó là, tôi có thể đi với một này. Trong Rails 3.1, bạn có thể có 2 loại Động cơ khác nhau, đầy đủ và có thể lắp (ở đây là an SO question talking about some of the differences). Nhưng về bản chất, bạn sẽ thay đổi Engine của mình thành công cụ có thể gắn kết, các tuyến đường trong công cụ có thể gắn kết được đặt tên và bạn có thể bao gồm chúng một cách rõ ràng trong tệp tuyến đường của ứng dụng chính của bạn, ví dụ::
Rails.application.routes.draw do
mount MyEngine::Engine => "/news"
end
Bạn cũng có thể điều chỉnh các tuyến động cơ được gắn và thực hiện tất cả các thứ khác lạ mắt (xem thêm thông tin here). Dài câu chuyện ngắn, nếu bạn có thể đi đến 3.1 thì đây là cách tiếp cận để sử dụng.
động Chèn các tuyến đường từ động cơ của bạn vào bạn chính App
Một trong những động cơ Rails nổi tiếng nhất xung quanh lúc này là lập mưu. Bây giờ, nghĩ ra là một công cụ có khả năng sẽ thêm khá nhiều tuyến đường vào ứng dụng của bạn, nhưng nếu bạn nhìn vào nguồn gốc, bạn sẽ thấy rằng nó không thực sự có một tệp config/routes.rb
nào cả! Điều này là bởi vì tự động thêm tính năng định tuyến của nó vào tệp routes.rb
của ứng dụng chính của bạn.
Khi bạn chạy trình tạo mô hình đi kèm với thiết lập, một trong những điều mà trình tạo sẽ làm là thêm một dòng như devise_for :model
ở đầu tệp routes.rb của bạn, ngay sau dòng Rails.application.routes.draw do
. Vì vậy, route.rb của bạn trông giống như này sau khi bạn thực hiện một máy phát điện để tạo ra một mô hình tài:
Rails.application.routes.draw do
devise_for :users
...
end
Bây giờ, devise_for là một phương pháp kỳ diệu mà đến như là một phần của devise (trong lib/devise/rails/routes.rb
), nhưng trong bản chất nó sẽ tạo một loạt các tuyến đường thông thường mà tất cả chúng ta đều biết dựa trên mô hình mà bạn đã tạo. Điều chúng ta cần biết, là cách đưa ra dòng này trong tệp ứng dụng routes.rb
, sau đó chúng ta có thể viết trình tạo trong công cụ của chúng tôi sẽ chèn bất kỳ tuyến đường nào của chúng tôi ở đầu các ứng dụng chính routes.rb
tệp. Đối với điều này, chúng tôi xem xét lib/generators/devise/devise_generator.rb
. Trong phương thức add_devise_routes
dòng cuối cùng là route devise_route
. Route
là một hành động Thor chèn chuỗi được chuyển vào chuỗi đó vào tệp routes.rb
của ứng dụng chính. Vì vậy, chúng ta có thể viết một máy phát điện của riêng của chúng tôi và làm điều gì đó tương tự như ví dụ .:
class MyCrazyGenerator < Rails::Generators::NamedBase
...
def add_my_crazy_routes
my_route = "match '/news', :to => 'bar_controller#foo_action'"
route my_route
end
end
Tất nhiên bạn sẽ cần phải chắc chắn rằng tất cả các cơ sở hạ tầng phát được đặt ra nhưng đó là bản chất của nó. Devise được viết bởi một số dudes rails rất thông minh và được sử dụng bởi khá nhiều người, thi đua những gì họ làm có thể là một cách khá tốt để đi. Trong số 3 điều mà tôi đề nghị, đây là cách tôi sẽ xử lý vấn đề của bạn (cho rằng việc chuyển sang đường ray 3.1 có lẽ không phải là một lựa chọn).
Bạn đã thử xem http://edgeguides.rubyonrails.org/configuring.html chưa? Tôi khá chắc chắn bạn có thể làm những gì bạn muốn bằng cách sử dụng móc & initializers –
Đó không phải là một bản sao của http://stackoverflow.com/questions/6310832/how-to-override-rails-app-routes-from-an- động cơ ? –
BTW, tôi tin rằng các tuyến động cơ luôn được tải sau các tuyến ứng dụng. –