Now that you know more about Modular Rails Architectures, I want to show you how you can build a very simple modular application. If you like it, don’t hesitate to subscribe to my newsletter below to learn when my book ‘Modular Rails’ (recently renamed) will be released.
This is the fifth article in the Modular Rails series. Here are the other posts:
- Modular Rails: Introduction
- Modular Rails: Use Cases
- Modular Rails: The Engines
- Modular Rails: Architectures
- Modular Rails: Create a modular app
- Modular Rails: F.A.Q
We’re going to build a very simple web application: A Todo List! To create this app, we will first generate a Rails application that will act as our parent app. Inside, we will generate a ‘Todo’ engine. Let’s go!
First, let’s generate a new Ruby on Rails application:
rails new ModularTodo
The next step is to generate an engine!
cd ModularTodo && rails plugin new todo --mountable
We will also create an ‘engines’ folder to store the engines (even if we just have one!).
mkdir engines && mv todo ./engines
Engines, just like gems, come with a
gemspec file. Let’s put some real values to avoid warnings.
# ModularTodo/engines/todo/todo.gemspec $:.push File.expand_path("../lib", __FILE__) # Maintain your gem's version: require "todo/version" # Describe your gem and declare its dependencies: Gem::Specification.new do |s| s.name = "todo" s.version = Todo::VERSION s.authors = ["Tibo"] s.email = ["email@example.com"] s.homepage = "//samurails.com" s.summary = "Todo Module" s.description = "Todo Module for Modular Rails article" s.license = "MIT" # Moar stuff # ... end
Now we need to add the
Todo engine to the parent application Gemfile.
# ModularTodo/Gemfile # Other gems gem 'todo', path: 'engines/todo'
bundle install. You should see the following in the list of gems:
Using todo 0.0.1 from source at engines/todo
Great, our Todo engine is loaded correctly! Before we start coding, we have one last thing to do: mount the Todo engine. We can do that in the
routes.rb file in the parent app.
Rails.application.routes.draw do mount Todo::Engine => "/", as: 'todo' end
We are mounting it at
/ but we could also make it accessible at
/todo. Since we have only one module,
/ is fine.
Now you can fire up your server and check it in your browser. You should see the default Rails view because we didn’t define any controllers/views yet. Let’s do that now!
Building the Todo list
We are going to scaffold a model named
Task inside the Todo module but to correctly migrate the database from the parent application, we need to add a small initializer to the
# ModularTodo/engines/todo/lib/todo/engine.rb module Todo class Engine < ::Rails::Engine isolate_namespace Todo initializer :append_migrations do |app| unless app.root.to_s.match(root.to_s) config.paths["db/migrate"].expanded.each do |p| app.config.paths["db/migrate"] << p end end end end end
That’s it, now when we run migrations from the parent application, the migrations in the Todo engine will be loaded too.
Let’s create the
Task model. The
scaffold command needs to be run from the engine folder.
cd engines/todo && rails g scaffold Task title:string content:text
Run the migrations from the parent folder:
Now, we just need to define the root route inside the Todo engine:
# ModularTodo/engines/todo/config/routes.rb Todo::Engine.routes.draw do resources :tasks root 'tasks#index' end
If you check your browser, you should see the following:
You can play with it, create tasks, delete them… Oh wait, the delete is not working! Why?! Well, it seems JQuery is not loaded, so let’s add it to the
application.js file inside the engine!
Yay, now we can destroy tasks!
Well that’s it! We just built a super simple and ugly Todo app in a modular way. Obviously, this was a super easy example so you can understand how it works.
Want to learn more?
You can also checkout the book I wrote about modular applications : Modular Rails.
Don’t hesitate to subscribe to my newsletter in the form below or on the book website to receive a free sample of the book.
You don’t want to wait? You want to read more about Ruby on Rails and modularity right now? Check this F.A.Q about modularity!