101 basic ruby/sinatra: undefined variable 'session' - ruby

app.rb:
require 'sinatra'
class MyApp < Sinatra::Application
enable :sessions
if session[:user_id].nil? then
erb :login
end
end
require_relative 'routes/init.rb'
config.ru:
require './app'
run MyApp
Running shotgun config.ru or thin start -R config.ru yields:
app.rb:3:in `<top (required)>': undefined local variable or method `session' for main:Object (NameError)
This is very 101ish. What gives?

I believe the problem is that you don't have that code within a get block or something similar. Basically, sinatra will only know about the session object in the context of a request. Something like this would work for the root url:
require 'sinatra'
class MyApp < Sinatra::Application
enable :sessions
get '/' do
if session[:user_id].nil? then
erb :login
end
end
end

Related

sinatra 'namespace' not working when trying modular way

Here is my code , but 'namespace' is not taking , If I write without namespace it is working , also it will work with 'namespace' if I remove class declaration and execute directly .
require 'sinatra'
require 'sinatra/namespace'
class MyApp < Sinatra::Base
namespace "/v1" do
get "/" do
"Hello World!"
end
end
end
1: from test1.rb:4:in <main>'
test1.rb:5:in': undefined method `namespace' for MyApp:Class (NoMethodError)
Based on the Sinatra documentation you need to register the extension:
require 'sinatra'
require 'sinatra/namespace'
class MyApp < Sinatra::Base
register Sinatra::Namespace
namespace "/v1" do
get "/" do
"Hello World!"
end
end
end

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") }

Cannot load such file in Test-Unit Sinatra

Im currently writing my test cases using ruby sinatra and im having a very weird or just im missing an important note/tip when writing a test cases using Test-Unit sinatra.
My problem is my my environments.rb is not being loaded in my test from my app.rb. but if i run it, it does get loaded.
here is my app.rb
require 'rubygems'
require 'sinatra'
require 'pg'
require './config/environments'
require './models/user'
module Registration
class HelloWorldApp < Sinatra::Base
helpers do
include Rack::Utils
alias_method :h, :escape_html
end
get '/' do
#title = " Introduction Biatch"
erb :index
end
post '/register' do
DB[:users].insert(username: params[:username],password: params[:password])
redirect '/view'
end
get '/view' do
#users = User.all
erb :view
end
get '/view/:id' do
#user = User.find(id: params[:id])
erb :edit
end
post '/edit/:id' do
#user = User.find(id: params[:id])
#user.update(username: params[:username],password: params[:password])
redirect '/view'
end
get '/delete/:id' do
#delete_user = User.find(id: params[:id])
#delete_user.delete
redirect '/view'
end
end
end
my environments.rb is in the config folder.
and here is my sample test cases. (not yet finished)
require 'rubygems'
require 'test/unit'
require 'test/unit/assertions'
require '../app/app'
module Registration
class TestCrud < Test::Unit::TestCase
# include Registration::HelloWorldApp
def test_insert_user
end
def test_get_all_user
end
def test_delete_all_user
end
end
end
and this is the error it throws.
C:/Ruby22-x64/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- ./config/environments (LoadError)
from C:/Ruby22-x64/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from C:/Users/John/Documents/Sinatra-Intro/app/app.rb:4:in `<top (required)>'
from C:/Ruby22-x64/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from C:/Ruby22-x64/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from test_crud.rb:4:in `<main>'
C:\Users\John\Documents\Sinatra-Intro\test>
Im very confused what did i do wrong. thanks in advance.
Ive found the answer, just change the require './config/environments' to require_relative. and change the require '../app/app' into require_into.

Set Up for RSpec in a Sinatra modular app

This is my first attempt with Sinatra. I built a simple classic app, set up RSpec for it, and got it working. Then, I tried to go modular, in a MVC fashion. Even though the app works in the browser, RSpec throws a NoMethodError. I've read Sinatra docs regarding RSpec, also searched a lot here in SO, but I can't find where the bug is. Any clue?
Thank you very much in advance.
Here are my relevant files:
config.ru
require 'sinatra/base'
Dir.glob('./{app/controllers}/*.rb') { |file| require file }
map('/') { run ApplicationController }
app.rb
require 'sinatra/base'
class ZerifApp < Sinatra::Base
# Only start the server if this file has been
# executed directly
run! if __FILE__ == $0
end
app/controllers/application_controller.rb
class ApplicationController < Sinatra::Base
set :views, File.expand_path('../../views', __FILE__)
set :public_dir, File.expand_path('../../../public', __FILE__)
get '/' do
erb :index
end
end
spec/spec_helper.rb
require 'rack/test'
# Also tried this
# Rack::Builder.parse_file(File.expand_path('../../config.ru', __FILE__))
require File.expand_path '../../app.rb', __FILE__
ENV['RACK_ENV'] = 'test'
module RSpecMixin
include Rack::Test::Methods
def app() described_class end
end
RSpec.configure { |c| c.include RSpecMixin }
spec/app_spec.rb
require File.expand_path '../spec_helper.rb', __FILE__
describe "My Sinatra Application" do
it "should allow accessing the home page" do
get '/'
expect(last_response).to be_ok
end
end
The error
My Sinatra Application should allow accessing the home page
Failure/Error: get '/'
NoMethodError:
undefined method `call' for nil:NilClass
# ./spec/app_spec.rb:5:in `block (2 levels) in <top (required)>'
I'm guessing you're following this recipe, correct?
The described_class in this line:
def app() described_class end
is meant to be the class under test, in this case ZerifApp. Try it like so:
def app() ZerifApp end
EDIT
It turns out the above answer is not correct about what described_class does. I assumed it was a placeholder -- actually it is an RSpec method that returns the class of the implicit subject, that is to say, the thing being tested.
The recipe at the link is misleading because of the way it recommends writing the describe block:
describe "My Sinatra Application" do
This is valid RSpec, but it does not define the subject class. Executing described_class in an example for this block will return nil. To make it work, replace the describe block:
describe ZerifApp do
Now described_class will return the expected value (ZerifApp)
https://pragprog.com/book/7web/seven-web-frameworks-in-seven-weeks
It has some source code to get some ideas from.
This has code example too. https://github.com/laser/sinatra-best-practices

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

Resources