Why is "url_for" undefined in my application? - ruby

I'm trying to use the url_for extension so my app can accurately find my static assets (tried the static assets extension as well, but it also complained of this same problem).
The problem is this:
undefined method `url_for' for Sinatra::Raffler:Class (NoMethodError)
Now, I've got the required modules listed, as per the url_for README:
require 'rubygems'
require 'sinatra/base'
require 'data_mapper'
require 'lib/authorization'
require 'pony'
gem 'emk-sinatra-url-for'
require 'sinatra/url_for'
But I'm still getting the NoMethodError when I try to call url_for
I have tried a couple of different things in regards to helpers. First, I have a helpers block for an authorization extension:
helpers do
include Sinatra::Authorization
end
So, I thought I could include the url_for helper in there:
helpers do
include Sinatra::Authorization
include Sinatra::UrlForHelper
end
But that didn't resolve the issue, so I just added the line:
helpers Sinatra::UrlForHelper
after that initial helpers do block, but still no resolution.

If you are subclassing Sinatra::Base, you need to include the helpers explicitly:
class Foobar < Sinatra::Base
helpers Sinatra::UrlForHelper
end

Related

Sinatra method `development?` undefined

The Sinatra docs say that development? will return true when the environment is development, but I receive an error stating that the method development? is undefined.
I tried skipping the shorthand and testing the ENV['RAKE_ENV'] variable itself, but it was just nil.
This is the error I'm getting:
undefined method `development?' for main:Object (NoMethodError)
and this is the code that is triggering the error:
require 'dm-sqlite-adapter' if development?
I am using the modular style app. The line above is an separate file that only manages the model. What's going on?
I struggled with this one, too. Here's what I discovered along the way.
You need to be "inside" a class that inherits from Sinatra::Base (such as Sinatra::Application, which inherits from Base) to be able to use the development? method, which is defined in base.rb.
In a classic Sinatra app you are already coding "inside" a class that inherits from Sinatra::Base. So development? will just work "anywhere".
In modular Sinatra the development? will only work in Sinatra::Base sub-classes, such as:
require 'sinatra/base'
# Placing
# require 'dm-sqlite-adapter' if development?
# here will not work.
class ApplicationController < Sinatra::Base
require 'dm-sqlite-adapter' if development? # But here it works
...
end
# Placing
# require 'dm-sqlite-adapter' if development?`
# AFTER the above class will still not work
class SomethingElse
# nor will `development?` work here, since it is called inside
# a class without Sinatra::Base inheritance
...
end
So basically you can use an ApplicationController class that inherits from Sinatra::Base and inside here check for development?. The same goes for sub-classes that inherits from your ApplicationController class:
class UserController < ApplicationController
require 'dotenv' if development?
...
end
For modular Sinatra, in the (main:Object) code text "outside" Sinatra::Base sub-classes, you need to follow Arup's instructions:
if Sinatra::Base.environment == :development
require 'awesome_print'
require 'dotenv'
Dotenv.load
...
end
Since you are using the modular style, you need to add the module namespace Sinatra::Base before the method.
So you will be able to access Sinatra::Base.development? anywhere in the app.

Error handlers don't run in modular Sinatra app

I have a Sinatra application that uses the modular style. Everything works fine apart from my error handler blocks which don't get invoked. Here's the relevant code:
app.rb
require_relative './routes/base'
require_relative './routes/routing'
module Example
class App < Sinatra::Application
use Routes::Base
use Routes::Routing
end
end
base.rb
require 'sinatra/base'
module Example
module Routes
class Base < Sinatra::Application
configure do
# etc.
end
# Error pages.
error 404 do # <- Doesn't get invoked.
erb :not_found
end
error 500 do # <- Doesn't get invoked.
erb :internal_server_error
end
end
end
end
routing.rb
module Example
module Routes
class Routing < Base
get '/?' do
erb :home
end
end
end
end
Why don't my error handlers work?
Thanks in advance.
The use method is for adding middleware to an app, you can’t use it to compose an app like this.
In your example you actually have three different Sinatra applications, two of which are being run as middleware. When a Sinatra app is run as middleware then any request that matches one of its routes is handled by that app, otherwise the request is passed to the next component in the Rack stack. Error handlers will only apply if the request has been handled by the same app. The app that you have defined the error handlers in has no routes defined, so all requests will be passed on down the stack — the error handlers will never be used.
One way to organise a large app like this would be to simply use the same class and reopen it in the different files. This other question has an example that might be useful: Using Sinatra for larger projects via multiple files.

Can't load my custom module in Sinatra

I am trying to load my custom module in Sinatra but when loading the app I get
'include' : Wrong argument type String (expected Module)
So in my app.rb I have
require './config/config.rb'
include 'MyConfig'
and my Module looks like so
module MyConfig
def config
environment = ENV["RACK_ENV"] || "development"
YAML.load_file("/config/config.yml")[environment]
end
end
I am trying to use the config.yml file to load some variables (i.e email credentials).
What am I doing wrong?
include is not like require. Include must be part of another class or Module body.
Do this:
require './config/config.rb'
class App
include MyConfig
# more code here
end
Include basically functions as an inline extension of the class or module that is currently in scope. It allows you to mix functionality into objects from external code without extending that external code.

How to use function present in one file in another file in watir ruby

I am new to Ruby and need help in accessing a function which is present in another file. The scenario is I have 2 files lets say test.rb and functions.rb
in test.rb i have the below code
require 'rubygems'
require 'watir'
require 'win32ole'
require 'erb'
require 'ostruct'
require 'C:\functions'
include Watir
U_RL="some url"
browser
if
ie.text.include?"There is a problem with this website's security certificate."
then
ie.link(:id, 'overridelink').click
end
now in the functions.rb file I have the below code
require 'rubygems'
require 'watir'
require 'win32ole'
include Watir
def browser
ie=IE.new
ie.maximize
ie.goto U_RL
ie.focus
ie.bring_to_front
ie.wait()
end
When I run test.rb, I get the error "Undefined local variable or method 'ie' for main:object
I can see that the browser is opened and even the the mentioned url is coming up, but when the security warning page comes up it is not clicking on ie.link(:id, 'overridelink').click.
Please let me know how to over come this
In your definition of the browser method, the scope of ie is local to that method. It can not be accessed outside of it.
This code needs to be completely refactored, but for now, you could just have browser return the local instance of ie, and set it in test.rb
functions.rb:
def browser
ie=IE.new
ie.maximize
ie.goto U_RL
ie.focus
ie.bring_to_front
ie.wait()
ie # last value is returned in ruby; can be explicit and do `return ie` as well
end
test.rb:
ie = browser
if ie.text.include?"There is a problem with this website's security certificate."
then
ie.link(:id, 'overridelink').click
end
You should require second file. Like this
require_relative 'functions'

Scaffolding Extensions: NoMethodError

Not sure if many people are familiar with Scaffolding Extensions for Ruby, but I've looked through their docs, forums, and even the source code of the Heroku test site, and not found an answer.
I made a basic Sinatra app and followed right from the RDoc's instructions:
require 'scaffolding_extensions'
require 'sinatra/base'
class Thingy < Sinatra::Base
scaffold_all_models
end
gives
undefined method 'scaffold_all_models' for Thingy:Class (NoMethodError)
and I know Scaffolding Extensions is loadable because I can successfully set some config variables in its classes.
This works for me:
require 'sinatra/base'
require 'scaffolding_extensions'
class Thingy < Sinatra::Base
scaffold_all_models
end

Resources