Reloading models and helpers with Sinatra::Reloader - windows

I'm trying to automatically reload a Sinatra project in JRuby on Windows Vista/7. I'm using Sinatra::Reloader from Sinatra-contrib. Unfortunately, it only seems to work for controllers. Any changes to models and helpers aren't reloaded.
Am I using also_reload incorrectly or something?
Here's what my project looks like:
/app.rb
require 'sinatra'
require 'sinatra/reloader'
require 'json'
class App < Sinatra::Application
enable :sessions
enable :logging
register Sinatra::Reloader
also_reload "models/*.rb"
also_reload "helpers/*.rb"
helpers do
include Rack::Utils
alias_method :h, :escape_html
end
end
require_relative 'helpers/init'
require_relative 'models/init'
require_relative 'controllers/init'
/controllers/init.rb
enable :sessions
require_relative 'auth'
require_relative 'customer'
require_relative 'policy'
require_relative 'forms'
/helpers/init.rb
require_relative 'auth_helper'
require_relative 'customer_helper'
require_relative 'flash_helper'
require_relative 'form_helper'
require_relative 'policy_helper'
/models/init.rb
require 'lib/sqljdbc4.jar'
require 'sequel'
require 'logger'
Java::com.microsoft.sqlserver.jdbc.SQLServerDriver
url = 'foo'
DB = Sequel.connect(url)
DB.loggers << Logger.new($stdout)
Sequel.inflections do |inflect|
inflect.clear :all
end
files = [
:customer,
:customer_email,
:phone_number ]
files.each do |f|
require_relative f.to_s
end

Under current implementation of yours, let's say you change something in helpers/auth_helper.rb. This file gets reloaded but since the helpers/init.rb is unchanged, it won't be reloaded by sinatra-reloader and you won't see the changes. Have you tried shotgun gem?

Related

Errno::ENOENT at / no such file or directory

I'm currently working on a sinatra app and im having a little problem.
i'm trying to load my index.erb but sinatra cannot find the index.erb.
Here is my app.rb
require 'rubygems'
require 'sinatra'
module Registration
class HelloWorldApp < Sinatra::Base
get '/' do
erb :index
end
end
end
and this is my Code hierarchy.
It keeps on looking in the directory: Sinatra-Intro/app/views/index.erb
but my views is in the: Sinatra-Intro/views/index.erb
You need to configure your application instance, something like this should work:
require 'rubygems'
require 'sinatra'
module Registration
class HelloWorldApp < Sinatra::Base
configure do
set :public_folder , File.expand_path('../public', __FILE__)
set :views , File.expand_path('../views', __FILE__)
set :root , File.dirname(__FILE__)
set :show_exceptions, development?
# Optional: Load from external file
#YAML.load_file('path/to/config.yml').each do |k, v|
# set(k.to_sym, v)
#end
end
get '/' do
erb :index
end
end
end
Then:
bundle exec rackup
You can change the default location with the view setting. Like this:
set :views, Proc.new { File.join(root, "views") }

How to map routes to modules without the use of multiple Sinatra apps?

I have this structure:
module Analytics
def self.registered(app)
module DepartmentLevel
departmentParticipation = lambda do
end
departmentStatistics = lambda do
end
app.get '/participation', &departmentParticipation
end
module CourseLevel
courseParticipation = lambda do
end
end
end
And at the end of the module Analytics I would like to route each piece of the request to his specific subModule. If it is requested
'analytics/department'
it should redirect to the module DepartmentLevel which has its own routes as
app.get 'participation', &departmentParticipation
I first thought on using map. But how to use it without having to run a new or inherit Sinatra::Base object?
Not sure if this is what you need, but here's how I build my modular Sinatra apps: By using use
First, I have my ApplicationController. It's the base class for all other Controllers. It lives in controllers/application_controller.rb
class ApplicationController < Sinatra::Base
# some settings that are valid for all controllers
set :views, File.expand_path('../../views', __FILE__)
set :public_folder, File.expand_path('../../public', __FILE__)
enable :sessions
# Helpers
helpers BootstrapHelpers
helpers ApplicationHelpers
helpers DatabaseHelpers
configure :production do
enable :logging
end
end
Now, all other Controllers/Modules inherit from ApplicationController. Example controllers/website_controller.rb:
require 'controllers/application_controller'
class WebsiteController < ApplicationController
helpers WebsiteHelpers
get('/') { slim :home }
get('/updates') { slim :website_updates }
get('/test') { binding.pry; 'foo' } if settings.development?
end
At last, in app.rb is where it all comes together:
# Require some stuff
require 'yaml'
require 'bundler'
Bundler.require
require 'logger'
# Require own stuff
APP_ROOT = File.expand_path('..', __FILE__)
$LOAD_PATH.unshift APP_ROOT
require 'lib/core_ext/string'
require 'controllers/application_controller.rb'
# Some Run-Time configuration...
ApplicationController.configure do
# DB Connections, Logging and Stuff like that
end
# Require ALL models, controllers and helpers
Dir.glob("#{APP_ROOT}/{helpers,models,controllers}/*.rb").each { |file| require file }
# here I glue everything together
class MyApp < Sinatra::Base
use WebsiteController
use OtherController
use ThingController
not_found do
slim :'404'
end
end
With this Setup, all I need to do in config.ru is
require './app.rb'
run MyApp
Hope this helps!

Sinatra tests always 404'ing

I have a very simple Sinatra app which I'm having trouble testing.
Basically, every single request test returns a 404 when I know from testing in the browser that the request works fine. Any ideas as to what the problem might be?
test_helper.rb:
ENV["RACK_ENV"] = 'test'
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
require 'app'
Sinatra::Synchrony.patch_tests!
class Test::Unit::TestCase
include Rack::Test::Methods
end
app_test.rb
require 'test_helper'
class AppTest < Test::Unit::TestCase
def app
#app ||= Sinatra::Application
end
def test_it_says_hello
get "/"
assert_equal 200, last_response.status
end
end
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development"
Bundler.require(:default, ENV["RACK_ENV"].to_sym)
require ENV["RACK_ENV"]
class App < Sinatra::Base register Sinatra::Synchrony
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
end
Gemfile
source :rubygems
gem 'daemons'
gem 'sinatra'
gem 'sinatra-synchrony', :require => 'sinatra/synchrony'
gem 'resque'
gem 'thin'
group :test do
gem 'rack-test', :require => "rack/test"
gem 'test-unit', :require => "test/unit"
end
Why can I not get this normally very simple thing working?
I had quite the same problem with only HTTP-404 coming in return.
I solved it with giving another return in the "app" function.
class IndexClassTest < Test::Unit::TestCase
def app
#app = Foxydeal #appname NOT Sinatra::Application
end
...
Also
Sinatra::Synchrony.patch_tests!
seems to be obsolete.
Under your app_test.rb do this instead of what you have now:
def app
#app ||= App.new
end
This will work with your your class style like you had it in the beginning, no need to switch to the non-class/modular style.
It may seem logical, but are your routes configured correctly? If a route isn't correctly configured, it'll throw 404 errors left and right.
Figured it out.
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development" Bundler.require(:default,
ENV["RACK_ENV"].to_sym) require ENV["RACK_ENV"]
class App < Sinatra::Base
register Sinatra::Synchrony
end
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
You may simply do this:
class AppTest < Test::Unit::TestCase
def app
Sinatra::Application
end
You can get a solid understanding of sinatra tests by reading Learning From the Masters: Sinatra Internals and Rack::Test

Load error when trying to include custom module

Same app, different problem. I'm working on an app using the Dan Benjamin "Meet Sinatra" screencast as a reference. I'm trying to include a custom authentication module, which is housed in a lib folder (lib/authentication.rb). I am requiring that line at the top of my code, but when I try to load the page, it claims there is no such file to load.
Any thoughts?
Here's the top of my main Sinatra file:
require 'sinatra'
require 'rubygems'
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/entries.db")
class Entry
include DataMapper::Resource
property :id, Serial
property :first_name, String
property :last_name, String
property :email, String
property :created_at, DateTime
end
# create, upgrade, or migrate tables automatically
DataMapper.auto_upgrade!
helpers do
include Sinatra::Authorization
end
And the actual Module:
module Sinatra
module Authorization
def auth
#auth ||= Rack::Auth::Basic::Request.new(request.env)
end
def unauthorized!(realm="Short URL Generator")
headers 'WWW-Authenticate' => %(Basic realm="#{realm}")
throw :halt, [ 401, 'Authorization Required' ]
end
def bad_request!
throw :halt, [ 400, 'Bad Request' ]
end
def authorized?
request.env['REMOTE_USER']
end
def authorize(username, password)
if (username=='topfunky' && password=='peepcode') then
true
else
false
end
end
def require_admin
return if authorized?
unauthorized! unless auth.provided?
bad_request! unless auth.basic?
unauthorized! unless authorize(*auth.credentials)
request.env['REMOTE_USER'] = auth.username
end
def admin?
authorized?
end
end
end
Then, on any of the handlers I want to protect, I put "require_admin."
Assuming you're using Ruby 1.9, the default $LOAD_PATH no longer includes the current directory. So while statements like require 'sinatra' work just fine (because those gems are in $LOAD_PATH), Ruby doesn't know that your lib/authorization file is located relative to your main Sinatra file.
You can add the Sinatra file's directory to the load path, and then your require statements should work fine:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
Personnaly, I use a "relative" path since I work with Ruby 1.9.2 :
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require './lib/authorization'
But I never check what would happen if my code should work on Ruby 1.8.6 again.

Sinatra/CouchDB error?

I'm working on my first Sinatra/CouchDB project and I'm getting an error I can't explain.
Here's my rackup (config.ru) file:
require 'rubygems'
require 'couchrest'
require 'patina'
set :environment, :development
set :root, File.dirname(__FILE__)
set :run, false
FileUtils.mkdir_p 'log' unless File.exists?('log')
log = File.new("log/sinatra.log", "a")
$stdout.reopen(log)
$stderr.reopen(log)
set :db, CouchRest.database!("http://127.0.0.1:5984/test")
run Sinatra::Application
And here's the app file (patina.rb):
require 'rubygems'
require 'sinatra'
require 'couchrest'
require 'haml'
class Article < CouchRest::ExtendedDocument
use_database settings.db
property :title
timestamps!
view_by :title
end
get '/' do
#db = settings.db
haml :index
end
Without the class definition in patina.rb, the route returns a page that displays the #db property as I was expecting. However, when I add the class definition to patina.rb I get "Ruby (Rack) application could not be started" error message.
Obviously this has something to do with my class definition, but I can't figure out what the problem is and the error message doesn't seem that helpful to me.
Also, I'd actually prefer to have the class definition in a separate file (Article.rb), but I can't figure out how to do that in the context of my Sinatra app.
Any help would be greatly appreciated!
EDIT:
See my answer below.
After a lot of googling, I discovered that the 1.4 series of json.gem are known to cause a lot of problems. I uninstalled all the json gems I had and installed json-1.2.4.gem instead. I have everything working correctly now. Here's the setup I'm using:
config.ru (Rackup file):
require 'application'
set :environment, :production
set :root, File.dirname(__FILE__)
set :run, false
FileUtils.mkmdir_p 'log' unless File.exists?('log')
log = File.new('log/sinatra.log', 'a+')
$stdout.reopen(log)
$stderr.reopen(log)
run Sinatra::Application
environment.rb:
require 'rubygems'
require 'couchrest'
require 'haml'
require 'ostruct'
require 'sinatra' unless defined?(Sinatra)
configure do
SiteConfig = OpenStruct.new(
:title => 'Application Title',
:author => 'Your Name',
:url_base => 'Your URL',
:url_base_db => 'Your CouchDB Server',
:db_name => "Your DB Name"
)
# load models
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
Dir.glob("#{File.dirname(__FILE__)}/lib/*.rb") { |lib| require File.basename(lib, '.*') }
end
lib/contact.rb (Model example, models auto-loaded in environment.rb):
class Contact < CouchRest::ExtendedDocument
include CouchRest::Validation
use_database CouchRest.database!((SiteConfig.url_base_db || '') + SiteConfig.db_name)
property :name
timestamps!
view_by :name
end
application.rb:
require 'rubygems'
require 'sinatra'
require 'environment'
configure do
set :views, "./views"
end
error do
e = request.env['sinatra.error']
Kernel.puts e.backtrace.join("\n")
'Application error'
end
helpers do
end
get '/new/?' do
haml :new
end
post '/save/?' do
#contact_name = params[:contact_name]
#contact = Contact.new
#contact.name = #contact_name
#contact.save
haml :save
end
get '/' do
haml :index
end
Hope this helps someone in the future!
try requiring 'patina' after setting :db. I think the class body of Article is executing the use_database method before the setting exists.
you should be able to put Article in article.rb (ruby naming convention is UpperCamel for classes, but under_scores for the files in which classes are defined) and then require 'article' in patina.rb.
thats the only thing that stood out for me, so let me know if that works.

Resources