Run example rails app from single file
Inspired by The Smallest Rails App, I wanted to easily try various concepts inside rails apps without having to deal with all that bloat from standard rails directory structure.
I went even further, not only reducing full rails app into single file (that has already been done) but to reducing a set of rails apps into single file 😎
More seriously, you can now create whole microservice architecture within a singe file and somebody else will be able to grasp it all and execute it locally. Or you can easily make a single file app and post it to StackOverflow (and people can actually run this code)
Just think about it. Proof of Concepts. Asking questions. Explaining concepts.
$ gem install minirails
Create a file myapp.rb
with the following content
# myapp.rb
define do |app|
class MainController < ActionController::Base
def index
render text: "Hello"
end
end
app.routes.draw do
get "/", to: "main#index"
end
end
then run
$ minirails myapp.rb
and that's it - you now have fully functional rails app running on port 5000!
You can run multiple applications from singe file
# file: multiple.rb
# usage: $ minirails multiple.rb
define "one" do |app|
app.routes.draw do
get "/", to: proc {|*| [200, {}, "Hello".lines] }
end
end
define "two" do |app|
app.routes.draw do
get "/", to: proc {|*| [200, {}, "World".lines] }
end
end
They will be run on ports 5000 and 5100 (and 5200 etc.)
You can also use full ActiveRecord capabilities.
The database (specified with ENV["DATABASE_URL"]
) will be recreated (drop & create & migrate) on every run
# file: database.rb
# usage: $ minirails database.rb
define "source" do |app|
# Configuration
ENV["DATABASE_URL"] = "postgresql://localhost/minirails_test"
# Migrations
class Migrations < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
end
# Seeds
User.create! [
{name: "Jon", email: "[email protected]"},
{name: "Hodor", email: "[email protected]"}
]
end
end
# Models
class User < ActiveRecord::Base
end
# Controllers
class UsersController < ActionController::Base
def index
render json: User.all
end
end
# Routes
app.routes.draw do
resources :users
end
end
You can start any rack compatible web app inside define block
or even generic worker process (sidekiq, clock, whatever)
by specifying :type
option.
# file: types.rb
# usage: $ minirails types.rb
# this is rails app
define "rails" do |app|
app.routes.draw do
get "/", to: proc {|*| [200, {}, "Hello from Rails".lines] }
end
end
# with type: :rack you need to return Rack-compatible app
define "rack", type: :rack do
proc {|*| [200, {}, "Hello from Rack".lines] }
end
# with type: :blank you can run anything
define "worker", type: :blank do
loop do
$stderr.puts "Hello from worker"
sleep 1
end
end
define "my-rails-app" do |app|
app.routes.draw do
get "/", to: proc {|*| [200, {}, "Hello from Rails".lines] }
end
end
# you can use :initialize option to load rails (or some rack)
# before loading worker code (similar to `rake environment`)
define "worker", type: :blank, initialize: "my-rails-app" do
loop do
Rails.logger.debug "Hello from worker with Rails env"
sleep 1
end
end
-
How to speed up loading?
Run
$ minirails --fast
and then usebin/minirails myapp.rb
instead
- Fork it ( https://github.com/teamon/minirails/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request