Has anyone gotten Padrino to work with Sprockets and Compass? - ruby

I'm on Padrino 0.10.7 and I haven't been able to get Sprockets to recognize Compass in the load path.

This is the only question on SO I've found on this topic.
Got this working with the following:
padrino-pipeline gem - going down the Sprockets route
Somewhere (I used my app.rb file) you will need the following:
Sass.load_paths << "#{Gem.loaded_specs['compass'].full_gem_path}/frameworks/compass/stylesheets"
Sass.load_paths << "#{Gem.loaded_specs['compass'].full_gem_path}/frameworks/blueprint/stylesheets"
Not sure if there is a simpler way. Feels like there should be. Also, any neat ways of getting image-url() sass method working?
EDIT: There is a way to get image-url working - if you thought the above was messy, add this to your app.rb too...
assets.context_class.class_eval do
def settings
YourAppName::App.settings
end
include Padrino::Helpers::AssetTagHelpers
end
(where YourAppName is the name of the module that describes your application, at the top of app.rb)

Related

How to access Padrino model and database in a "standalone" (bin/) script? [duplicate]

I have a Padrino App called Gusy that specifies (Sequel) Models like
# gusy/models/seminar.rb
class Seminar < Sequel::Model
# hopefully irrelevant stuff defined here
end
I want to access this Model from either a second gem, or a script in bin/.
Now, e.g. I require Gusy from a second gem "gusy_fill". The Gemfile is put up to set the path to a Gusy git repository. I can successfullly see the Gusy namespace (and e.g. print the apps Version Gusy::VERSION) if interactively exploring with bundle console.
How can I access the mapped models and where and how do I configure the database connection?
I see nothing relevant in the Padrino:: or Gusy:: modules.
An irb session might look like this:
require 'gusy'
Gusy::Seminar.create(:name => 'from gusy_fill' # => NameError: uninitialized constant Gusy::Seminar
I want to achieve this without creating a second Padrino App that mounts Gusy (for that, pointers are included in the generated gusy/README.md).
As initially statet, I would have the very same issue, if I would do what I want from within the same app: write a small script in gusy/bin that talks with the database, really in the setting like when calling padrino console.
Sorry to hear you're having trouble with this. It's good that you brought it up though because I've been trying to put my thoughts around the subject for a while now and this pushed me into it :). I've prepared a repo for you explaining how to do it with what we have now in Padrino.
The README (which I'm pasting afterwards), explains the reasoning behind it and puts some questions up for us to think about the way we've implemented them. I'd love to hear your thoughts about it :).
Gemified apps in Padrino
This repo intends to answer
How to access Padrino model and database in a “standalon” (bin/) script? and
How to access a gemified Padrino Apps Model from other gem that requires that App.
The issue
In short, there are two issues of the similar nature, both related to models defined in the gemified app:
they need to be accessed from another gems/projects;
they need to be accessed from the gemified app's bin, doing something else other than starting
the Padrino server.
The example
First there's gemified-app. That's a Padrino app that is gemified. It also contains a model
called SomeModel that has one field called property.
Then there's access-gemified-app-without-padrino; a ruby script that loads the gemified app to
access the model.
Finally, there's another-app which is a regular Padrino app that just loads gemified-app to use
its model (SomeModel).
Problems with the current Padrino setup
Creating an app with padrino g project gemified-app --orm sequel --gem --tiny will give you the
following gemspec:
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/gemified-app/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Darío Javier Cravero"]
gem.email = ["dario#uxtemple.com"]
gem.description = %q{Padrino gemified app example}
gem.summary = %q{Padrino gemified app example}
gem.homepage = ""
gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "gemified-app"
gem.require_paths = ["lib", "app"]
gem.version = GemifiedApp::VERSION
gem.add_dependency 'padrino-core'
end
The key points are gem.require_paths = ["lib", "app"] and gem.add_dependency 'padrino-core'.
gem.require_paths = ["lib", "app"] explains why models/some_model.rb isn't available when we
load the gem somewhere else. It simple isn't added to $LOAD_PATH :(.
gem.add_dependency 'padrino-core' hints us that something might be missing later on. What happens
with dependencies like the ORM or the renderer? Should we load those? I reckon that it's a matter
of what you want to achieve but I'd say that most times yes.
Our gemified app dependencies are still listed in our Gemfile which will only be added in the
current scope and not in any gems requiring our gemified-app gem.
A first attempt at solving this
For this to work there are two things we should do:
Add 'models' to gem.require_paths = ["lib", "app"] so that it becomes:
gem.require_paths = ["lib", "app", "models"].
That will make sure that anything inside the gemified-app/models directory is included in your
gem.
To make it easier to test this, we'll use bundler and in our access-gemified-app-without-padrino
test script we'll add a Gemfile that looks like this:
source 'https://rubygems.org'
gem 'gemified-app', path: '../gemified-app'
gem 'pry'
Now in your new app, go to the REPL bundle exec pry and try to require 'gemified-app'.
Then try SomeModel.all. It will fail. Why? Because you didn't require 'some_model'.
It will still not work if you do that though. Why? Because none of the model's dependencies,
i.e. sequel and sqlite3 (not a direct dependency but it is through the connection) are loaded.
Here you have two choices: you load them manually on your Gemfile or you define them as
dependencies on gemified-app.gemspec.
I regard the latter one as a better choice since you're already including the model and you're
expecting its dependencies to come with it. It would like this:
# gemified-app/gemified-app.gemspec
# ...
gem.add_dependency 'padrino-core'
gem.add_dependency 'padrino-helpers'
gem.add_dependency 'slim'
gem.add_dependency 'sqlite3'
gem.add_dependency 'sequel'
gem.add_development_dependency 'rake'
# ...
# gemified-app/Gemfile
source 'https://rubygems.org'
# Distribute your app as a gem
gemspec
You would have to explicitly include all the gems you will need. This may seem cumbersome but in
all fairness it gives you a greater understanding of what your app needs. Eventually you will
realise you don't even need bundler and the Gemfile :).
Alright, so, go ahead launch your REPL and type require 'gemified-app' and require 'some_model'.
Then try SomeModel.all. And... It will fail :(. Why? Because Sequel::Base isn't defined. Now you might be wondering:
what happened to the reference to sequel I put in my gemified-app.gemspec? Well, it's just that:
a reference and it won't require the gem for you.
This won't happen with Padrino either because we're using
require 'rubygems' unless defined?(Gem)
require 'bundler/setup'
Bundler.require(:default, RACK_ENV)
in our config/boot.rb and that only loads required gems on our Gemfile.
So the question is... Should we load that manually? And if so, where?
Well, since this is a gem itself, I believe that the best place to do so would be in lib/gemified-app.rb.
Loading all the gems needed will make this file look like:
require 'padrino-core'
require 'padrino-helpers'
require 'slim'
require 'sqlite3'
require 'sequel'
module GemifiedApp
extend Padrino::Module
gem! "gemified-app"
end
Alright, so we're all set... Back to the REPL, do your requires
require 'gemified-app'
require 'some_model'
and try SomeModel.all. And... It will fail :(. Again! :/ Why? Because there's no connection to the
database. Padrino was loading this for us through config/database.rb.
Another question arises... Should we include config/database.rb in the gem too?
The way I see it, we shouldn't. The way I see it, the database connection is something every app
should locally define as it may contain specific credentials to access it or stuff like that.
Our sample, access-gemified-app-without-padrino/do-somethin.rb script will then look like this:
require 'gemified-app'
Sequel::Model.plugin(:schema)
Sequel::Model.raise_on_save_failure = false # Do not throw exceptions on failure
Sequel::Model.db = Sequel.connect("sqlite:///" + File.expand_path('../../gemified-app/db/gemified_app_development.db', __FILE__), :loggers => [logger])
require 'some_model'
SomeModel.all.each do |model|
puts %Q[#{model.id}: #{model.property}]
end
Yes, the connection code is pretty much the same than our Padrino app and we're reusing its database
for this example.
That was some ride :) but we finally made it. See the sample apps in the repo for some working
examples.
require some_model :/
I don't know you but I don't like that at all. Having to do something like that means that I
really have to pick my models' names very carefully not to clash with anything I may want to use
in the future.
I reckon that modules are the answer to it but that's the current state of affairs. See the
conclusion for more on this.
An alternative approach
Separate your model layer into its own gem and require it from your (gemified or not) Padrino app.
This might probably be the cleanest as you can isolate tests for your models and even create
different models for different situations that may or may not use the same database underneath.
It could also encapsulate all of the connection details.
Conclusion
I think we should review Padrino's approach to gemified apps.
Should we use the gemspec instead of the Gemfile for hard dependencies?
Should we namespace the models (I know we had some issues in the past with this)?
Should we teach users to do explicit requires in their gems or to inspect the dependecies and
require them for them?
Should we teach our users how to load their dependencies and be more reponsible about it? At the end
of the day, if they went the gemified app route they are clearly much more proficient in Ruby and
should be aware of this kind of stuff.
Thoughts? :)

How to access a gemified Padrino Apps Model from outside (not in controller, but e.g. a standalone script)

I have a Padrino App called Gusy that specifies (Sequel) Models like
# gusy/models/seminar.rb
class Seminar < Sequel::Model
# hopefully irrelevant stuff defined here
end
I want to access this Model from either a second gem, or a script in bin/.
Now, e.g. I require Gusy from a second gem "gusy_fill". The Gemfile is put up to set the path to a Gusy git repository. I can successfullly see the Gusy namespace (and e.g. print the apps Version Gusy::VERSION) if interactively exploring with bundle console.
How can I access the mapped models and where and how do I configure the database connection?
I see nothing relevant in the Padrino:: or Gusy:: modules.
An irb session might look like this:
require 'gusy'
Gusy::Seminar.create(:name => 'from gusy_fill' # => NameError: uninitialized constant Gusy::Seminar
I want to achieve this without creating a second Padrino App that mounts Gusy (for that, pointers are included in the generated gusy/README.md).
As initially statet, I would have the very same issue, if I would do what I want from within the same app: write a small script in gusy/bin that talks with the database, really in the setting like when calling padrino console.
Sorry to hear you're having trouble with this. It's good that you brought it up though because I've been trying to put my thoughts around the subject for a while now and this pushed me into it :). I've prepared a repo for you explaining how to do it with what we have now in Padrino.
The README (which I'm pasting afterwards), explains the reasoning behind it and puts some questions up for us to think about the way we've implemented them. I'd love to hear your thoughts about it :).
Gemified apps in Padrino
This repo intends to answer
How to access Padrino model and database in a “standalon” (bin/) script? and
How to access a gemified Padrino Apps Model from other gem that requires that App.
The issue
In short, there are two issues of the similar nature, both related to models defined in the gemified app:
they need to be accessed from another gems/projects;
they need to be accessed from the gemified app's bin, doing something else other than starting
the Padrino server.
The example
First there's gemified-app. That's a Padrino app that is gemified. It also contains a model
called SomeModel that has one field called property.
Then there's access-gemified-app-without-padrino; a ruby script that loads the gemified app to
access the model.
Finally, there's another-app which is a regular Padrino app that just loads gemified-app to use
its model (SomeModel).
Problems with the current Padrino setup
Creating an app with padrino g project gemified-app --orm sequel --gem --tiny will give you the
following gemspec:
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/gemified-app/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Darío Javier Cravero"]
gem.email = ["dario#uxtemple.com"]
gem.description = %q{Padrino gemified app example}
gem.summary = %q{Padrino gemified app example}
gem.homepage = ""
gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "gemified-app"
gem.require_paths = ["lib", "app"]
gem.version = GemifiedApp::VERSION
gem.add_dependency 'padrino-core'
end
The key points are gem.require_paths = ["lib", "app"] and gem.add_dependency 'padrino-core'.
gem.require_paths = ["lib", "app"] explains why models/some_model.rb isn't available when we
load the gem somewhere else. It simple isn't added to $LOAD_PATH :(.
gem.add_dependency 'padrino-core' hints us that something might be missing later on. What happens
with dependencies like the ORM or the renderer? Should we load those? I reckon that it's a matter
of what you want to achieve but I'd say that most times yes.
Our gemified app dependencies are still listed in our Gemfile which will only be added in the
current scope and not in any gems requiring our gemified-app gem.
A first attempt at solving this
For this to work there are two things we should do:
Add 'models' to gem.require_paths = ["lib", "app"] so that it becomes:
gem.require_paths = ["lib", "app", "models"].
That will make sure that anything inside the gemified-app/models directory is included in your
gem.
To make it easier to test this, we'll use bundler and in our access-gemified-app-without-padrino
test script we'll add a Gemfile that looks like this:
source 'https://rubygems.org'
gem 'gemified-app', path: '../gemified-app'
gem 'pry'
Now in your new app, go to the REPL bundle exec pry and try to require 'gemified-app'.
Then try SomeModel.all. It will fail. Why? Because you didn't require 'some_model'.
It will still not work if you do that though. Why? Because none of the model's dependencies,
i.e. sequel and sqlite3 (not a direct dependency but it is through the connection) are loaded.
Here you have two choices: you load them manually on your Gemfile or you define them as
dependencies on gemified-app.gemspec.
I regard the latter one as a better choice since you're already including the model and you're
expecting its dependencies to come with it. It would like this:
# gemified-app/gemified-app.gemspec
# ...
gem.add_dependency 'padrino-core'
gem.add_dependency 'padrino-helpers'
gem.add_dependency 'slim'
gem.add_dependency 'sqlite3'
gem.add_dependency 'sequel'
gem.add_development_dependency 'rake'
# ...
# gemified-app/Gemfile
source 'https://rubygems.org'
# Distribute your app as a gem
gemspec
You would have to explicitly include all the gems you will need. This may seem cumbersome but in
all fairness it gives you a greater understanding of what your app needs. Eventually you will
realise you don't even need bundler and the Gemfile :).
Alright, so, go ahead launch your REPL and type require 'gemified-app' and require 'some_model'.
Then try SomeModel.all. And... It will fail :(. Why? Because Sequel::Base isn't defined. Now you might be wondering:
what happened to the reference to sequel I put in my gemified-app.gemspec? Well, it's just that:
a reference and it won't require the gem for you.
This won't happen with Padrino either because we're using
require 'rubygems' unless defined?(Gem)
require 'bundler/setup'
Bundler.require(:default, RACK_ENV)
in our config/boot.rb and that only loads required gems on our Gemfile.
So the question is... Should we load that manually? And if so, where?
Well, since this is a gem itself, I believe that the best place to do so would be in lib/gemified-app.rb.
Loading all the gems needed will make this file look like:
require 'padrino-core'
require 'padrino-helpers'
require 'slim'
require 'sqlite3'
require 'sequel'
module GemifiedApp
extend Padrino::Module
gem! "gemified-app"
end
Alright, so we're all set... Back to the REPL, do your requires
require 'gemified-app'
require 'some_model'
and try SomeModel.all. And... It will fail :(. Again! :/ Why? Because there's no connection to the
database. Padrino was loading this for us through config/database.rb.
Another question arises... Should we include config/database.rb in the gem too?
The way I see it, we shouldn't. The way I see it, the database connection is something every app
should locally define as it may contain specific credentials to access it or stuff like that.
Our sample, access-gemified-app-without-padrino/do-somethin.rb script will then look like this:
require 'gemified-app'
Sequel::Model.plugin(:schema)
Sequel::Model.raise_on_save_failure = false # Do not throw exceptions on failure
Sequel::Model.db = Sequel.connect("sqlite:///" + File.expand_path('../../gemified-app/db/gemified_app_development.db', __FILE__), :loggers => [logger])
require 'some_model'
SomeModel.all.each do |model|
puts %Q[#{model.id}: #{model.property}]
end
Yes, the connection code is pretty much the same than our Padrino app and we're reusing its database
for this example.
That was some ride :) but we finally made it. See the sample apps in the repo for some working
examples.
require some_model :/
I don't know you but I don't like that at all. Having to do something like that means that I
really have to pick my models' names very carefully not to clash with anything I may want to use
in the future.
I reckon that modules are the answer to it but that's the current state of affairs. See the
conclusion for more on this.
An alternative approach
Separate your model layer into its own gem and require it from your (gemified or not) Padrino app.
This might probably be the cleanest as you can isolate tests for your models and even create
different models for different situations that may or may not use the same database underneath.
It could also encapsulate all of the connection details.
Conclusion
I think we should review Padrino's approach to gemified apps.
Should we use the gemspec instead of the Gemfile for hard dependencies?
Should we namespace the models (I know we had some issues in the past with this)?
Should we teach users to do explicit requires in their gems or to inspect the dependecies and
require them for them?
Should we teach our users how to load their dependencies and be more reponsible about it? At the end
of the day, if they went the gemified app route they are clearly much more proficient in Ruby and
should be aware of this kind of stuff.
Thoughts? :)

Tests won't work with MongoMapper in Sinatra

I hooked up MongoMapper with Sinatra and everything works fine except for the testing. I have Autotest with Rack Testing and Rspec installed. Whenever I run autotest, it tells me
/home/jason/ror/sbmongo/main.rb:11:in `<top (required)>': uninitialized constant
MongoMapper (NameError)
Here is the line of code it refers to in my main.rb file.
MongoMapper.database = 'testdb'
What is the problem and how could I fix this?
The order that things are called via require in Ruby does make a difference, as a constant declared in a library will only be visible after a the library has been required.
When running RSpec, it's best to put general set up code in one place - the spec_helper.rb file - and then in the individual specs, (for example, when specing main.rb) require 'spec_helper and then require main.rb. If each code file requires the libraries it needs in the right order, then your specs will run without a problem too. If not, it's a sign that the order of requires isn't quite right.

Tutorials to Testing using RSPEC on PADRINO framework on RUBY

I am new to Ruby and have been asked to use it in our new project. We have also been asked to use Padrino (Sinatra) as backend/framework. For testing we have been asked to use Rspec. I have been hunting for tutorials for long that would guide in using Rspec for Ruby on Padrino. What I get is mostly with reference to RoR. But, I am in need of Ruby on Padrino.
Please guide me for the same with any starters/guides/references/discussions, etc.
Please correct me, if I am wrong anywhere. May be I haven't searched with the right combination of words/phrases for my issue.
I am using Ruby 1.9.3 and Padrino v.0.10.6.
Note : I have also referred the SO question, but it didn't help.
I never used Padrino, but it seems that it isn't much different from Sinatra.
I suggest reading Sinatra and RSpec resources.
You can get started with this:
How to use rspec in a Sinatra Application
Sinatra, RSpec and DataMapper: Configuring and using a database for tests
And by reading specs that were written by other people on GitHub. These are some of mine, but they are not the cleanest thing that exists.
EDIT: a short tutorial
Getting started with this framework is much quicker and easier than with Sinatra. :)
Install Padrino: gem install padrino
Create an application: padrino g project myapp -d datamapper -t rspec
The command speaks for itself. :)
Run the tests: rspec --color
No tests were found, obviously. Let's create one in spec/hello/hello_spec.rb:
require File.dirname(__FILE__) + "/../spec_helper.rb"
describe "get '/'" do
it "should display hello world" do
get '/'
last_response.body.should == "Hello world!"
end
end
Run the tests again.
They failed, because no route get '/' exists. Let's create it.
In app/controllers/hello.rb:
Myapp.controller do
get '/' do
"Hello world!"
end
end
Run the test: it passes!
Check Padrino's documentation for more information and cool features, such as the controllers generator and the admin interface.
Good luck!

Is there a Rack or Sinatra based environment configuration utility?

Is there anything in the Sinatra / Rack world similar to Rails configuration loading scheme that loads one of the config\enviroments\*.rb files depending on Rails.env
I know I could develop one pretty easily, i was just wondering if there was something already in place.
If you're following the Rails convention of putting a file for each environment in config/environments/environment_name.rb, you can put something like this in your Sinatra app, or for Rack in your config.ru file:
Dir.glob(File.dirname(__FILE__) + "/config/environments/#{settings.environment}.rb", &method(:require))
With some minor modifications you could make it load other file locations/combinations. Sinatra's configure blocks work just as well, too.
It turns out that there is something from Sinatra, that provides a similar, though limited, functionality.
See the code:
https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1120
So that you can do this:
class MyApp < Sinatra::Base
configure :development, :test do
#only executes this code when environment is equal to one of the passed arguments
# I'm pretty sure Sinatra sets this based on ENV['RACK_ENV']
end
end
There is one called Sinatra::ConfigFile, which now lives in Sinatra::Contrib http://www.sinatrarb.com/contrib/config_file.html
There's lots of useful stuff in there.
I adapted mine from monkrb.com (it's also yaml in RoR anyways)
YAML.load_file(path_of "config/settings.yml")[RACK_ENV]
e.g.
http://github.com/codepants/yasumi/blob/master/config/settings.yml

Resources