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:
- Create new gem with bundler or jeweler or something else.
- Insert your application code to lib/ directory of your gem.
- 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.
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
Activerecord Objects in Hashes Aren't Garbage Collected -- a Bug or a Sort of Caching Feature
An Error Occurred While Installing Debugger-Linecache (1.1.1), and Bundler Cannot Continue
How to Load a Spec_Helper.Rb Automatically in Rspec 2
Convert Datetime String to Utc in Rails
Ruby Concatenate Strings and Add Spaces
How to Send Mail with Rails Without a Template
How to Get Request.Uri in Model in Rails
Understanding Io.Select When Reading Socket in Ruby
What's the Difference Between a Class and the Singleton of That Class in Ruby
Using a Ruby Script to Login to a Website via Https
How to Define_Method in Rails Models
Rails Routing (Root :To => ...)
Disable Rvm or Use Ruby Which Was Installed Without Rvm
Using Question Mark Character in Rails/Activerecord Column Name
Bundle Install Could Not Fetch Specs from Https://Rubygems.Org/