ruby-on-railsrubygemsruby-on-rails-5rails-enginesruby-on-rails-plugins

How to include a plugin/engine in a rails application?


This is my first time interaction with a rails plugin and I'm unable to wrap my head around how this thing works. I'm going to make a rails plugin/engine. I want to include this plugin in my rails application(a different project), how can I do it? I found this which suggests to

At the root of this brand new engine's directory lives a plugin_name.gemspec file. When you include the engine into an application later on, you will do so with this line in the Rails application's Gemfile:

gem 'plugin_name', path: 'engines/plugin_name'

My question is that how exactly do I do it? I mean when I create a rails application I do not find any engines directory in the folder structure. And also which directories from the plugin project do I have to place in the engines/ directory?
I created a plugin by doing

rails plugin new plugin_name --mountable

and it generated following files/directories:

|-app/
|-bin/                
|-config/
|-demo_project.gemspec
|-Gemfile
|-Gemfile.lock
|-lib/
|-MIT-LICENSE
|-Rakefile
|-README.md
|-test
  |-dummy
    |-(contains a rails application)

Now once I'm done with this plugin, how do I include this in another rails application? What directories do I need to put in engines/ in addition to including the plugin in the gemfile?

In addition to this I also want some info about what the following is indicating

Additionally, the --mountable option tells the generator to mount the engine inside the dummy testing application located at test/dummy by adding the following to the dummy application's routes file at test/dummy/config/routes.rb:

mount PluginName::Engine => "/plugin_name"

What does the mount point indicate and what will be it's role once the plugin is included in a rails application?


Solution

  • Rails engine is an isolated rails app, that is mounted inside main app. Two main reasons to create an engine are isolation of an application part (with possible intent to split the app into pieces) and code reuse (when you use same engine in several apps)

    Technically it is a ruby gem, but often engines start (and live) as an isolated part of a larger app, without being completely extracted into own repository, gem publishing etc. For example, if you have admin part of your app, you can make it an engine:

    # in gemfile:
    gem 'admin', path: 'engines/admin'
    
    # routes:
    mount Admin::Engine => '/admin'
    
    # engine's routes:
    resources :foo # => because of being in an engine this will be /admin/foo
    

    directory structure can look like:

    |-app/
    |-bin/
    |-...
    |-config/
      |-application.rb
      |-routes.rb
    |-engines/
      |-admin_engine/
        |-app/
          |-controllers/admin/
              |- foo_controller.rb
        |-config/
          |-routes.rb # <- this is engine's routes
        |-lib/
          |-admin/
            |-engine.rb
        |- admin.gemspec