How to Convert an Existing Rails 3 Application into an Engine

How do I convert an existing Rails 3 Application into an Engine?

Too many questions here to answer them all properly. This is one of those things that will pay off for you by just digging in and trying it out. As you get deeper into it, come back and ask new specific questions.

Here are some of the resources I used when I recently did this.

  • http://www.themodestrubyist.com/2010/03/05/rails-3-plugins---part-2---writing-an-engine/
  • http://www.themodestrubyist.com/2010/03/16/rails-3-plugins---part-3---rake-tasks-generators-initializers-oh-my/
  • http://pragprog.com/titles/jvrails/crafting-rails-applications
  • http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/

For the most part, you can keep the things in your app directory where they are. You should also be able to keep your routes.rb in the config directory, but there can be some gotchas if some of your routes collide with those of the app.

You will likely want to create a generator to create a migration that has all of the tables your engine requires. Other generators can be created to override default views and that sort of thing.

Do create a test application that uses your gem. Many of the issues you will run into are making sure you are loading your engine's dependencies properly. While you are in development, edit the Gemfile of your test application to point straight to the source of your gem... something like this:

gem 'my-forum', :path => '~/work/my-forum'

Namespacing

You should at least name your tables/models so you don't run into naming collisions. Looking at your current forum app, I'd at least prefix all of your tables with 'forum_'. It is quite likely that someone using your engine will have a different model named Category for example... so ForumCategory would be a better choice.

Definitely namespace any classes you create in the lib directory.

Config Files

You'll want to keep your routes.rb in the config directory. You may also need to keep your initializers around as well. Any app specific things will likely need to get moved elsewhere.

Public Files

With Rails 3.0.x, you can keep stylesheets and javascripts in the public directory. I think there is a bit of code you need to add to your Engine class though...

initializer "static assets" do |app|
app.middleware.use ::ActionDispatch::Static, "#{root}/public"
end

How to convert existing rails application to gem

You're describing a rails engine. Engine is a miniature rails application that can be used inside other rails app. For more details see official rails guide

Extracting a Rails application into a plugin or engine

Actually, converting an application is pretty straigtforward. Just create a plugin-folder, put an app-folder inside containing all yor model-views-controllers folders, and that's it.

You will have to manage your migrations yourself though. Also you have to define rake-tasks to copy files to your public folder. I think the railscasts is still pretty up-to-date, if anything it is now easier in rails 2.3.

Good luck!

[EDIT: for rails3] Rails 3 engines are very clean and powerful. Check this gist by Jose Valim.

How to convert a rails app to a gem?

Since Rails 3.0 any Rails app is an Engine. For wrap your application to a gem you should:

  1. Create new gem with bundler or jeweler or something else.
  2. Insert your application code to lib/ directory of your gem.
  3. All classes of your app should be in MyGem module, so add MyGem before your class names, like: Article => MyGem::Article. All your controllers, models, etc. should be namespaced with module GemName.
  4. Your file lib/my_gem.rb should contain next code:

    module MyGem
    class Engine < Rails::Engine; end
    end

UPD

Or be better if you will use mountable engines:

$ rails plugin new MyGem

It generates mountable engine with dummy app for tests and gemspec.

How can I make routes from a Rails 3 engine available to the host application?

Change config.routes in your engine to:

Rails.application.routes.draw do  # NOT MyEngineName::Engine.routes.draw
resources :classrooms
end

The way you have it, the routes are only available in the MyEngineName::Engine namespace and not in the rest of the host rails application.

There used to be a blog post with more info, but unfortunately it is no longer available:

  • http://blog.loopedstrange.com/modest-rubyist-archive/rails-3-plugins-part2-writing-an-engine

How to pass the session variables from one rails 3.2.8 engine to another engine?

From the Rails Edge guide:

4.3.2 Using a controller provided by the application

Because Rails controllers generally share code for things like authentication and accessing session variables, by default they inherit from ApplicationController. Rails engines, however are scoped to run independently from the main application, so each engine gets a scoped ApplicationController. This namespace prevents code collisions, but often engine controllers should access methods in the main application's ApplicationController. An easy way to provide this access is to change the engine's scoped ApplicationController to inherit from the main application's ApplicationController. For our Blorgh engine this would be done by changing app/controllers/blorgh/application_controller.rb to look like:

class Blorgh::ApplicationController < ApplicationController
end

By default, the engine's controllers inherit from Blorgh::ApplicationController. So, after making this change they will have access to the main applications ApplicationController as though they were part of the main application.

This change does require that the engine is run from a Rails application that has an ApplicationController.



Related Topics



Leave a reply



Submit