Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails 3.1.1 engines - with mountable engines, is it possible to access parent app assets, default layout?

This is more for experimentation - I am aware that I can do this with --full but I wanted the functionality of namespacing in the app to avoid conflicts

The idea is to have a main app - which handles authentication, common items, admin screens etc Then creating engines to add further functionality like

  • crm
  • cms
  • blog
  • wiki
  • forum
  • etc

These engines I can pick and choose as I need for whatever kind of app I am building. Is this possible?

Is it just the case of applying both --mountable and --full options?

Experimenting - would there be any issue if I use the full option add rspec and then simple add

rails plugin new plugin_name --skip-test-unit --full --dummy-path=spec/dummy

and in lib\plugin_name\engine.rb

module PluginName
  class Engine < Rails::Engine

    # this is added by rails when an engine is mountable 
    # to isolate the plugin and prevent name clashes
    isolate_namespace PluginName

    # one of the additions to make rspec work from command line for the plugin
    config.generators do |g|
      g.test_framework :rspec, :view_specs => false
    end   
  end
end 

I have already created both --full and --mountable engines and have rspec finally working for anyone reading there are some great articles (see below), but wondered of the wider impact of doing this for the solution I am trying to create

I am still playing with this and will post my findings..
Any help/discussion will be massively appreciated.

Please Note

  1. Why I want to do it - build once use many times...
  2. I would never want a non-tech/client to add "plugins/engines" - this is purely to entertain point 1.

Issues I am Having...

  1. Running the server on the top level app. Only when accessing content from the engine, (I can see by the error messages) I have a routing problem (root_path undefined or devise routes missing) - the parent application layout is being rendered, I can see it in the extracted source of the error. Progress but no cigar just yet!

Useful References

  • Engines vs Mountable Apps
  • 3.1 engines with rspec
  • testing rails 3 engines
  • Listing Routes in a Mountable engine
like image 366
Spasm Avatar asked Oct 11 '11 08:10

Spasm


2 Answers

I managed to get this working with the following steps:

  1. In my parent app I was mounting the engine in routes.rb

    mount PluginName::Engine => '/plugin_name'
    

    I just removed it.

  2. Created an application controller as Ryan Bigg below had stated.

    class PluginName::ApplicationController < ApplicationController
      ...
    end
    
  3. As I wanted to have things name spaced when generating controllers, models, tests so you have to essentially comment out the isolate_namespace PluginName lib\plugin_name\engine.rb when I wanted the gem to be run in the parent app.

    It is not yet an ideal solution. off the top off my head, I could use something like:

    isolate_namespace PluginName if %w[development testing].include?(Rails.env)
    

    but will have to test if this is practical.

Kudos to Ryan for helping me find my way many thanks

Furthermore, the same can be done with the --mountable switch version and all you need to do is one further step in your engines config/routes.rb replace

PluginName::Engine.routes.draw do

with

Rails.application.routes.draw do
like image 64
Spasm Avatar answered Sep 28 '22 01:09

Spasm


Yes, you can reference the parent application assets just by referencing them in your application like normal:

  <%= stylesheet_link_tag "application %>

Although, not sure why you would want to do that because...

I'm going to answer your first question with the answer to your second question.

To use the application's layout you will need to modify the ApplicationController in the engine (which is namespaced) and have it inherit from ApplicationController in the engine.

That will then have the controllers for the engine using the layout provided by the engine. I'm doing this in my engine, forem.

One day, this will be covered in the Engines Guide that, at this time of writing, is currently being written.

like image 42
Ryan Bigg Avatar answered Sep 28 '22 01:09

Ryan Bigg