2011-09-28 13 views
12

Tôi có móc nối trước trong bộ điều khiển ứng dụng chính của ứng dụng thực hiện như sau: (Nó không chỉ đặt liên kết trong flash, có thông báo, nhưng nó không liên quan đến câu hỏi, nó chỉ truy cập các tuyến đường trong phương pháp này)Các tuyến động cơ trong Bộ điều khiển Ứng dụng

class ApplicationController < ActionController::Base 
    before_filter :set_link 

    def set_link 
    flash[:notice] = items_path 
    end 
end 

này hoạt động tốt cho các ứng dụng, tuy nhiên khi tôi đi vào bộ điều khiển cho động cơ tôi đã làm tôi nhận được ngoại lệ

No route matches {:controller=>"items", :action=>"index"} 

tôi hiểu khi ở trong động cơ, những người trợ giúp tuyến đường dành cho động cơ trừ khi tiền tố d với main_app

Vì vậy, việc thay đổi phương pháp trong điều khiển ứng dụng để

def set_link 
    flash[:notice] = main_app.items_path 
    end 

Gets thoát khỏi ngoại lệ nhưng tôi thực sự không muốn phải làm điều đó. Có giải pháp nào khác để động cơ nhận ra các tuyến main_app không?

CHỈNH SỬA:

Điều này cũng xảy ra nếu bố cục ứng dụng gọi cho người trợ giúp đường dẫn. Vì vậy, nếu động cơ được thiết kế để tích hợp vào bố cục của main_app thì vấn đề này sẽ cắt lên đó.

+1

Có gì sai với 'main_app'? Bên cạnh đó, tại sao bạn đang giới thiệu một phụ thuộc vào động cơ của bạn từ ứng dụng chính, theo cách này, công cụ của bạn phụ thuộc vào 'items_path' được định nghĩa trong ** mọi ứng dụng ** sử dụng nó. Đây không phải là một thực hành tốt, thông thường bạn chỉ nên sử dụng 'main_app.root_path', hoặc một số tuyến đường nổi tiếng khác (ví dụ nếu bạn sử dụng' dev_ sign_in_path'). – Fabio

+0

items_path sẽ được xác định trong ứng dụng chính đã được tạo. Và tôi muốn có động cơ được gắn ở đâu đó nhưng được tích hợp vào bố cục của ứng dụng hiện tại. Động cơ chính nó không bao giờ tham khảo items_path cả. Tôi chỉ muốn các chế độ xem được tạo bởi công cụ để được đưa vào phần thân của bố cục ứng dụng. Tuy nhiên, bố cục ứng dụng cần truy cập vào các tuyến đường của main_app – Olives

+0

Điều này xuất phát từ sự cần thiết phải có động cơ và ứng dụng chia sẻ cùng một bố cục. Bằng cách đó khi người dùng đi từ một trang trên ứng dụng chính, đến một trang trên công cụ, không có sự khác biệt rõ ràng giữa bố cục. – Olives

Trả lời

18

Động cơ có thể lắp được thiết kế để hoạt động như thế này, đó là cách ly các tuyến ứng dụng chính và các tuyến động cơ.

Nếu bạn muốn hai tập hợp các tuyến đường được hợp nhất, bạn có thể sử dụng một động cơ không bị cô lập.Bước đầu tiên là loại bỏ các cuộc gọi isolated_namespace phương pháp trong định nghĩa công cụ của bạn:

module MyEngine 
    class Engine < Rails::Engine 
    isolate_namespace MyEngine # remove this line 
    end 
end 

Bước thứ hai là để chuyển đổi các tuyến đường của bạn trong my_engine/config/routes.rb, bạn nên đi từ này:

MyEngine::Engine.routes.draw do 
    # stuff that routes things 
end 

này:

Rails.application.routes.draw do 
    # stuff that routes things 
end 

và xóa cuộc gọi phương thức mount trong các tuyến đường của ứng dụng:

App::Application.routes.draw do 
    mount MyEngine::Engine => "/engine" # remove this line 
end 

Ưu điểm chính của nó làm theo cách này sẽ là:

  1. Không cần phải ray khỉ vá. Tôi biết đã nghĩ ra điều này, nhưng điều này có thể còn sót lại từ những ngày mà động cơ không tồn tại trong đường ray.

  2. Không cần gắn động cơ trong các tuyến ứng dụng. Mặt khác, điều này có thể phản tác dụng nếu bạn muốn kiểm soát chính xác hơn điểm chèn khi tất cả các tuyến động cơ của bạn sẽ được gọi sau (hoặc trước đó, tôi không có câu trả lời cho câu hỏi này) các tuyến đường chính của bạn.

Nếu bạn đang tìm tài liệu về động cơ, rails docs for the Engine class là điểm khởi đầu khá tốt. Tôi khuyên bạn nên đọc chúng (trong trường hợp bạn chưa có) nếu bạn quan tâm đến chủ đề này.

+0

Cảm ơn người đàn ông, tôi đã kéo tóc ra ... –

+0

bạn quên lưu ý, nếu bạn xóa 'isolation_namespace', bạn có thể để lộ xung đột tên với ứng dụng chính hoặc các loại đá quý khác (ví dụ: người giúp đỡ) – montrealmike

+0

Không thể upvote nó nhiều hơn nữa! – Nerve

4

Tôi đã tìm ra cách thực hiện việc này. Các vấn đề nằm trong không gian tên bị cô lập. Để tích hợp động cơ với các ứng dụng và chia sẻ cùng một bố trí (có thể có người giúp đỡ đường đi từ ứng dụng chính) Tôi đã làm điều này:

Trước hết tôi loại bỏ config/routes.rb từ động cơ

Sau đó, tôi loại bỏ các isolate_namespace từ lớp cơ

module MyEngine 
    class Engine < Rails::Engine 
- isolate_namespace MyEngine 
    end 
end 
end 

tôi đã thêm một tập tin đó đã được nạp trong công cụ:

module ActionDispatch::Routing 
    class Mapper 
    def mount_my_engine_at(mount_location) 
     scope mount_location do 
     #Declare all your routes here 
     end 
    end 
    end 
end 

Cuối cùng, trong ứng dụng chính của config/routes.rb thay vì 'mount'ing động cơ, bạn có thể gọi phương thức của bạn

mount_my_engine_at "mount_location" 

này sẽ cơ bản 'gắn' động cơ của bạn như là một phần của ứng dụng chính thay vì được phân lập từ nó. Nó cũng tương tự như cách Devise cũng vậy.

0

Cách đơn giản nhất là để vẽ các tuyến đường trong cả hai ứng dụng chính, và động cơ, để họ có thể truy cập đến cả hai:

[MyEngine::Engine, App::Application].each do |app| 
    app.routes.draw do 
    # Declare all your routes here 
    end 
end 
2

Bạn có thể giữ isolate_namespace. Trong routes.rb động cơ của bạn

MyEngine::Engine.routes.draw do 
    ... 
    root to: "something#index" 
end 

Rails.application.routes.draw do 
    get "something", to: "my_engine/something#index" 
end 

Và sau đó trong ứng dụng routes.rb chính

Rails.application.routes.draw do 

    mount MyEngine::Engine => "/anything_you_want" 

    root to: "main#index" 
end 

Bằng cách này bạn có thể chọn những gì tuyến đường mà bạn muốn để lộ (và bạn không)