|
SinatraReloaded
Getting Started guide for Sinatra with focus on development environment
Featured IntroductionThis guide is based on GettingStarted guide, but extends it with templating changed to HAML. The Rack::Reloader is used for reloading development environment. Local installationIt's important to understand that development environment for the appengine and the Jruby contain 3 different places of ruby gems:
System ruby gems installationFirst, make sure that you have the latest version of gem installed $ gem --version 1.3.5 $ # If you have the older version perform upgrade $ gem update --system $ # Install the required system gems $ gem install --no-rdoc --no-ri google-appengine Application gems installationCreate the folder for application. In this guide it's assumed to be ~/guestbook/. $ mkdir guestbook $ cd guestbook In order to manage gems one need to create the Gemfile control file. Ours will be pretty simple. $ cat >Gemfile <<EOF disable_system_gems disable_rubygems bundle_path ".gems/bundler_gems" gem "sinatra" gem "dm-core" gem "dm-appengine" gem "haml" EOF Creating applicationFirst let's create the config.ru, which will configure application and reloading for development environment. The simple use Rack::Reloader will not work as we need to reload the Sinatra framework. $ cat >config.ru <<EOF
require 'appengine-rack'
require 'guestbook'
AppEngine::Rack.configure_app(:application => "guestbook", :version => 1)
configure :development do
class Sinatra::Reloader < ::Rack::Reloader
def safe_load(file, mtime, stderr)
if File.expand_path(file) == File.expand_path(::Sinatra::Application.app_file)
::Sinatra::Application.reset!
stderr.puts "#{self.class}: reseting routes"
end
super
end
end
use Sinatra::Reloader
end
run Sinatra::Application
EOFThe reloader example, above, assumes that application is Sinatra traditional style application and all routes defined in the 'guestbook.rb' file, or main file of the application. If application has a separate file for routes, for example 'route.rb', then ::Sinatra::Application.app_file should be replaced with './route.rb' or similar. What is meant here is that you need to do .reset! only in case when file with routes changes. If you routes scattered in different files you need to write more complex reloading strategy. If you are using 'sinatra/base' instead of the traditional Sinatra application, you, probably, already found out, that you should take care about everything yourself. And the reloader is no exception. Everywhere, where ::Sinatra::Application mentioned, you need to replace it with your class. Assume following example: require 'sinatra/base'
class Simple < Sinatra::Base
get '/' do
'Hello World!'
end
endthen your reloader should do Simple.reset! for file with routes. And, of course, you need to change run Sinatra::Application to run Simple.new. Now, let's get back and put the application itself $ cat >guestbook.rb <<EOF
require 'sinatra'
require 'dm-core'
require 'haml'
# Configure DataMapper to use the App Engine datastore
DataMapper.setup(:default, "appengine://auto")
# Create your model class
class Shout
include DataMapper::Resource
property :id, Serial
property :message, Text
end
# Set Haml output format and enable escapes
set :haml, {:format => :html5 , :escape_html => true }
# Main board
get '/' do
# Just list all the shouts
@shouts = Shout.all
haml :index
end
post '/' do
# Create a now shout and redirect back to the list
shout = Shout.create(:message => params[:message])
redirect '/'
end
EOFLet's add some templates as well $ mkdir views First, the above-mentioned index.haml $ cat >views/index.haml <<EOF
%h2 Messages
- for shout in @shouts
%p<
Someone wrote,
%q= shout.message
%form{:method => :post}
%textarea{:name => :message}
%br/
%input{:type => :submit, :method => :Shout}
EOFAnd the layout for the application $ cat >views/layout.haml <<EOF
!!!
%html
%head
%title Guestbook
%body
!= yield
EOFRunning serversNow, finally we are ready to run the development with Sinatra reloading. $ dev_appserver.rb . The Rack::Reloader uses mtime on your system, so if the reloader is not doing its job try touch guestbook.rb. Enjoy! all question and improvements are welcome in the google group |
I tried to use your reloader but it fails because I have a diferent file for all my models. When I save any file in my application, the application starts sending a not found in every in route... any advice?
Richard, how do you include the code in your application? Reloader works only with "require" and does not with "load". Do you see in the log the "reloaded" message ?
when running appcfg.rb bundle . i get:
/usr/lib/ruby/site_ruby/1.8/rubygems.rb:280:in `activate': can't activate bundler (= 0.6.0, runtime) for ["appengine-tools-0.0.5"], already activated bundler-0.7.0 for (Gem::LoadError?)
Trying to overcome it usging JRuby:
jruby -S appcfg.rb bundle .
i get nothing and gems.jar is not even generated....
this is bug in current version - see bug 36 . Uninstall bundler v 0.7.0 with your MRI ruby and install v 0.6.0
gem uninstall bundler
gem install bundler -v 0.6.0
or, alternatively, don't install bundler manually as mentioned above, then correct version will be installed with google-appengine gem.
I'm getting this error on Ubuntu. I think it's a user permission issue with the library. All my other ruby gems work fine, so it may be an issue with appengine-jruby and Ubuntu.
/usr/lib/ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require': no such file to load -- appengine-tools/dev_appserver (LoadError?)
Also, bundler do not install gems for java platform. May be better install gems through old solutions while builder do not updated.
In the last section, under "Install deployment gems and create local structure", "appcfg.rb gem bundle" is deprecated. The new syntax is displayed, however, when that is used a classpath exception is thrown. This happened on Cygwin.
See: http://groups.google.com/group/appengine-jruby/browse_thread/thread/bae51f86fc5b5063
got error org.jruby.rack.RackInitializationException?: No such file or directory - /Users/eiffel/web/guestbook/file:/Users/eiffel/web/guestbook/WEB-INF/lib/gems.jar!/bundler_gems/jruby/1.8/gems/haml-3.0.0/VERSION
getting the same error
eiffelqiu & rsaccon : downgrade to haml 2.2.24 should be fine.. pls use mailing list as it's more suitable for questions, plus tons of ppl there with answers.
Based on this guide, i have succesfully deployed my first innate-based app in google appengine. As you should know innate is the core of the ramaze web framework. I wrote a short guide on http://innate-gae.appspot.com including the appropriate Gemfile and config.ru . Thnx.
failure #1
Caused by: org.jruby.exceptions.RaiseException???: (NoMethodError???) undefined method `configure_app' for AppEngine???::Rack:Module
Fix by commenting out:
# AppEngine???::Rack.configure_app(:application => "guestbook", :version => 1)
http://groups.google.com/group/appengine-jruby/browse_thread/thread/2a512ce3294892db
failure #2:
#<NameError??: uninitialized constant DataMapper??::Adapters::AppEngineAdapter??::Extlib>
http://code.google.com/p/appengine-jruby/issues/detail?id=93
fix by downgrading dm-core to 1.0.2
still getting this error on startup: /usr/local/lib/ruby/gems/1.8/gems/appengine-tools-0.0.17/lib/appengine-tools/dev_appserver.rb:86:in `exec': Operation not supported - java (Errno::E045)
but app seems to work.
Many thanks for the hints above, working a treat now!
BTW, I wouldn't suggest doing this:
$ # If you have the older version perform upgrade $ gem update --system
It turns out that you need to be on rubygems <= 1.3.7 rather than the latest (1.8.5 as of the time of writing). Also worth noting you need to be using a ruby 1.8.7 interpreter, not a 1.9.1+ interpreter.
Downgrading to dm-core 1.0.2 worked for me as well. To make this easy I just modified in Gemfile where dm-core is a dependency to: gem "dm-core", "= 1.0.2"