Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

init commit

  • Loading branch information...
commit a3e61a29f767da48fa333fbc43c1bb7039bc5ea2 0 parents
@bmizerany bmizerany authored
91 README.md
@@ -0,0 +1,91 @@
+Sinatra ActiveRecord Extension
+========================
+
+Extends [Sinatra](http://www.sinatrarb.com/) with a extension methods and Rake
+tasks for dealing with a SQL database using the [ActiveRecord ORM](http://api.rubyonrails.org/).
+
+Install the `sinatra-activerecord` gem along with one of the database adapters:
+
+ sudo gem install activerecord sinatra-sequel
+ sudo gem install sqlite3
+ sudo gem install mysql
+ sudo gem install postgres
+
+adding this to your `Rakefile`
+
+ require 'sinatra/activerecord/rake'
+
+ $ rake -T
+ rake db:create_migration # create an ActiveRecord migration in ./db/migrate
+ rake db:migrate # migrate your database
+
+create a migration
+
+ $ rake db:create_migration NAME=create_users
+ $ vim db/migrate/20090922043513_create_users.rb
+
+ class CreateUsers < ActiveRecord::Migration
+ def self.up
+ create_table :users do |t|
+ t.string :name
+ end
+ end
+
+ def self.down
+ end
+ end
+
+run the migration
+
+ $ rake db:migrate
+
+I like to split models out into a separate `database.rb` file and then
+require it from the main app file, but you can plop
+the following code in about anywhere and it'll work just fine:
+
+ require 'sinatra'
+ require 'sinatra/activerecord'
+
+ # Establish the database connection; or, omit this and use the DATABASE_URL
+ # environment variable or the default sqlite://<environment>.db as the connection string:
+ set :database, 'sqlite://foo.db'
+
+ # At this point, you can access the Sequel Database object using the
+ # "database" object:
+ puts "the foos table doesn't exist" if !database.table_exists?('foos')
+
+ # models just work ...
+ class User < ActiveRecord::Base
+ end
+
+ # see:
+ Foo.all
+
+ # access the models within the context of an HTTP request
+ get '/foos/:id' do
+ @foo = Foo.find(params[:id])
+ erb :foos
+ end
+
+Copyright (c) 2009 Blake Mizerany
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
61 lib/sinatra/activerecord.rb
@@ -0,0 +1,61 @@
+require 'uri'
+require 'time'
+require 'sinatra/base'
+require 'activerecord'
+require 'logger'
+
+module Sinatra
+ module ActiveRecordHelper
+ def database
+ options.database
+ end
+ end
+
+ module ActiveRecordExtension
+ def database=(url)
+ @database = nil
+ set :database_url, url
+ database
+ end
+
+ def database
+ @database ||= (
+ url = URI(database_url)
+ ActiveRecord::Base.logger = activerecord_logger
+ ActiveRecord::Base.establish_connection(database_options)
+ ActiveRecord::Base
+ )
+ end
+
+ protected
+
+ def database_options
+ url = URI(database_url)
+ if url.scheme == "sqlite"
+ {
+ :adapter => "sqlite3",
+ :database => url.host
+ }
+ else
+ {
+ :adapter => url.scheme,
+ :host => url.host,
+ :port => url.port,
+ :database => url.path[1..-1],
+ :username => url.user,
+ :password => url.password
+ }
+ end.merge(database_extras)
+ end
+
+ def self.registered(app)
+ app.set :database_url, lambda { ENV['DATABASE_URL'] || "sqlite://#{environment}.db" }
+ app.set :database_extras, Hash.new
+ app.set :activerecord_logger, Logger.new(STDOUT)
+ app.database # force connection
+ app.helpers ActiveRecordHelper
+ end
+ end
+
+ register ActiveRecordExtension
+end
37 lib/sinatra/activerecord/rake.rb
@@ -0,0 +1,37 @@
+require 'activerecord'
+require 'fileutils'
+
+namespace :db do
+ desc "migrate your database"
+ task :migrate do
+ ActiveRecord::Migrator.migrate(
+ 'db/migrate',
+ ENV["VERSION"] ? ENV["VERSION"].to_i : nil
+ )
+ end
+
+ desc "create an ActiveRecord migration in ./db/migrate"
+ task :create_migration do
+ name = ENV['NAME']
+ abort("no NAME specified. use `rake db:create_migration NAME=create_users`") if !name
+
+ migrations_dir = File.join("db", "migrate")
+ version = ENV["VERSION"] || Time.now.utc.strftime("%Y%m%d%H%M%S")
+ filename = "#{version}_#{name}.rb"
+ migration_name = name.gsub(/_(.)/) { $1.upcase }.gsub(/^(.)/) { $1.upcase }
+
+ FileUtils.mkdir_p(migrations_dir)
+
+ open(File.join(migrations_dir, filename), 'w') do |f|
+ f << (<<-EOS).gsub(" ", "")
+ class #{migration_name} < ActiveRecord::Migration
+ def self.up
+ end
+
+ def self.down
+ end
+ end
+ EOS
+ end
+ end
+end
38 spec/spec_sinatra_activerecord.rb
@@ -0,0 +1,38 @@
+root = File.expand_path(File.dirname(__FILE__) + '/..')
+$: << "#{root}/lib"
+
+require 'sinatra/base'
+require 'sinatra/activerecord'
+
+class MockSinatraApp < Sinatra::Base
+ register Sinatra::ActiveRecordExtension
+end
+
+describe 'A Sinatra app with ActiveRecord extensions' do
+ before {
+ File.unlink 'test.db' rescue nil
+ ENV.delete('DATABASE_URL')
+ @app = Class.new(MockSinatraApp)
+ #@app.set :migrations_log, File.open('/dev/null', 'wb')
+ }
+
+ it 'exposes the Sequel database object' do
+ @app.should.respond_to :database
+ end
+
+ it 'uses the DATABASE_URL environment variable if set' do
+ ENV['DATABASE_URL'] = 'sqlite://test-database-url.db'
+ @app.database_url.should.equal 'sqlite://test-database-url.db'
+ end
+
+ it 'uses sqlite://<environment>.db when no DATABASE_URL is defined' do
+ @app.environment = :foo
+ @app.database_url.should.equal "sqlite://foo.db"
+ end
+
+ it 'establishes a database connection when set' do
+ @app.database = 'sqlite://test.db'
+ @app.database.should.respond_to :table_exists?
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.