コアといくつかのモジュールで構成されるアプリケーションを作成しています。モジュールはRailsエンジンであり、コア自体がホストとしてのみ機能するため、実際の機能を提供します。エンジンは/lib
からホストされ、それぞれのパスにマウントされます。
coreApp
└──lib
├── module1
├── module2
└── etc
次に、モジュールは次のようにマウントされます
mount Module1::Engine => "/module1", :as => "module1"
mount Module2::Engine => "/module2", :as => "module2"
ログイン自体はモジュールによって実行されますが、コアはセッションの処理も担当します。
コアアプリケーションのレイアウトをエンジンと共有するための優れた方法をまだ見つけていません。今のところ、これは私がレイアウトをエンジンで利用できるようにする方法です:
coreApp
└── app
└── views
└── layouts
├── application.html.erb
└── core.html.erb
ファイルcore.html.erb
には
<%= render :template => 'layouts/application' %>
このように各モジュールに含まれています
module Module1
class ApplicationController < ActionController::Base
layout "core"
end
end
特にエレガントではありませんが、正常に機能し、モジュールのコンテンツは、アプリケーションレイアウトのyield
ステートメントの場所にレンダリングされます。
問題は次のとおりです。
アクティブなモジュールのスタイルシートを含める方法が必要です。
ヘッダーには、次のようなログインユーザーに関する情報が含まれています。
Logged in as <%= @user[:realname] %>
これはコアから来ていますhome_controller
def index
@user = User.find_by_id(session[:user])
end
しかし、モジュールにアクセスしようとすると、次のエラーが発生します
NoMethodError in Module1/home#index
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
明らかに@user
を参照しています。
エンジン側をあまり改ざんすることなく、これを可能な限りエレガントにDRY)で解決するにはどうすればよいでしょうか。
私はこれをグーグルで検索しましたたくさんしかしそれを解決する方法について頭を悩ませることはできません。 Railsがどのように機能するかについての洞察がまったくない可能性があるため、Railsをよく知っている人にとって、この質問が意味をなさない可能性があります。 。
不明な点やあいまいな点があればコメントしてください。詳しく説明します。
使用する layout 'layouts/application'
また、main_app.your_pathを使用したくない場合は、次を追加することもできます。
module YourEngine
module ApplicationHelper
def method_missing(method, *args, &block)
if (method.to_s.end_with?('_path') || method.to_s.end_with?('_url')) && main_app.respond_to?(method)
main_app.send(method, *args)
else
super
end
end
end
end
私も自分のアプリケーションで同じことをしました。私がしたのは:
Application_controllerをに変更します
module EngineModule
class ApplicationController < ::ApplicationController
layout 'layouts/application'
end
end
あなたの見解では、login_path
などのパスを参照する場合は、main_app.login_path
を介して参照できます。