Rails 3: How to declare Rack middleware in application.rb - ruby-on-rails-3.1

Many examples such as these two:
How to use rack middleware with Rails3?
http://asciicasts.com/episodes/151-rack-middleware
define middleware in a class and then add
config.middleware.use "ClassNameHere"
to config/application.rb but I can't figure where in application.rb to add this. I have put it inside of class Application < Rails::Application. I am also not sure if there is a specific location where I put my middleware class. I have mine in /lib.
Say my middleware class is called ResponseTimer, I receive the following error when I run rake middleware:
uninitialized constant ResponseTimer
Please note that I am in Rails 3.1 and not 2.x which is why I am not putting the config.middleware.use in environment.rb

add config.autoload_paths += %W(#{config.root}/lib) to config/application.rb See here https://github.com/radar/guides/blob/master/rails-lib-files.md

Related

No route matches [GET] "/" when trying to add the gem devise

The error comes with
Please add some routes in config/routes.rb.
routes.rb already has
devise_for :users
I am not sure how to fix this error. I have tried rake routes in the GIT terminal with the result:
rake aborted!
Don't know how to build task 'routes' (See the list of available tasks with `rake --tasks`)
Running in development mode on local server.
So few things:
Firstly, rake routes has been removed - I have no idea why tbh, but it is rails routes now instead.
Secondly, devise is adding its routes, but you still need to have some ohter content that devise is to guard access to. You can create a simple HomeController:
class HomeController < ApplicationController
def show
render html: "home"
end
end
and use this as your root route:
# routes.rb
devise_for ...
root to: "home#show"

annotate gem not working after including custom module inside model

After i include custom module inside model, annotate stop working and give me error:
My model: app/models/hotel.rb
class Hotel < ActiveRecord::Base
include HotelHandler
...
end
Custom helper class: app/helpers/hotel_handler.rb
module HotelHandler
...
end
This give me error:
uninitialized constant Hotel::HotelHandler (NameError)
If you want to setup Rails style auto and eager loading in a plain old Ruby project the modern way is to use Zeitwerk:
# this file would be the "entry path" to your application such as config.ru
# loads an installs gems inline
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'zeitwerk'
end
root = Pathname.new(File.expand_path(__dir__))
env = ENV.fetch("MYAPP_ENV", 'development')
loader = Zeitwerk::Loader.new
# Mimics Rails by adding every subdirectory of `/app` and `/app/**/concerns`
# as "root directories" where zeitwerk will find top level constants
paths = [
dir[root.join('app/*/')]
dir[root.join('app/**/concerns')]
].flatten.each do |path|
loader.push_dir(path) if File.directory?(path)
end
# makes zeitwerk reload classes when they change
loader.enable_reloading if env == 'development'
loader.setup
# loads all classes on boot for performance
loader.eager_load if env == 'production'
This is really just a quick and dirty minimal example and you would usually enscapsulate this logic into a bootstapping file and an "Application" class.

Rails and MiniTest: How to write tests for something in app/lib/mymodule (Class not found)?

Rails 5.2 here.
I want to test a class defined in app/lib/legacy/export.rb:
# app/lib/legacy/export.rb
module Legacy
class Export
def initialize ; end
end
end
However, a test in test/services/legacy_export_test.rb
# test/services/legacy_export_test.rb
require 'test_helper'
class LegacyExportTest < ActiveSupport::TestCase
test 'can be initialized' do
Legacy::Export.new
end
end
will spit out NameError: uninitialized constant Legacy::Export.
It works well if I put the class definition in app/lib/export.rb (and remove the module definition).
I can also reference this class in Controllers and in the rails console (rails c).
Trying to reference the class starting with the top-level-"namespace" (::Legacy::Export) does not help either. I find answers to questions how to reference lib folders (and subdirectories) in the test/ folder, but this is not what I need.
require 'lib/legacy/export will tell me cannot load such file, as will require 'legacy/export'.
I assumed that the (Auto-)Load-stuff of Rails and MiniTest are the same, but obviously there is some additional configuration to be done.
What has to be done? Where would I find this information?
The problem is that your class namespace / class path doesn't match how Rails autoloading works out of the box.
When you use a class that wasn't previously declared, Rails by default will look on specific paths (defined on config.autoload_paths)
app/controllers
app/controllers/concerns
app/models
app/models/concerns
...
When you use User for the first time, as it's not defined (yet) it will loop over those paths and try to require app/controllers/user.rb, app/controllers/concerns/user.rb, app/models/user.rb, until it founds the User class
if your class is namespaced as Legacy::Export, then it will look for app/models/legacy/export.rb, app/models/concerns/legacy/export.rb, app/controllers/legacy/export.rb, etc.
That's why it can't find your class: Your file is located on app/lib, that's not within the paths Rails use to look for.
There are different solutions:
Option #1
Require the file explicitly. (The Ruby way)
require_relative '../../app/lib/legacy/export'
Option #2
Add app/lib to autoload_path (in config/application.rb)
(The Rails Way)
module YourApp
class Application < Rails::Application
# ...
config.autoload_paths << Rails.root.join("app/lib")
end
end
Option #3
Adapt namespace to match what autoloading expects (instead of changing the configuration)
Example: move you file to something like app/models/legacy/export.rb

How to set authentication in Sinatra?

I need simple authentication for blog. For a single person. Just login to the website
Can't configure sinatra_warden. Write the line
require 'rubygems'
require 'sinatra'
require 'pry-byebug'
require "sinatra/activerecord"
require "carrierwave"
require "carrierwave/orm/activerecord"
require 'sinatra_warden'
require 'warden'
register Sinatra::Warden
use Rack::Session::Pool
in app.rb, but I get an error
NoMethodError: undefined method `register' for main:Object
the gem sinatra_warden has installed. as well written require "warden" & require "sinatra_warden"
sinatra_warden 0.3.2
warden 1.2.6
When I add the authorize! method in controller, I get an error
undefined method `authorize!'
Because you didn't use the sinatra/base you should add sinatra/namespace. Add to your app.rb this require require "sinatra/namespace".
Sinatra::Namespace is an extension that adds namespaces to an
application. This namespaces will allow you to share a path prefix for
the routes within the namespace, and define filters, conditions and
error handlers exclusively for them. Besides that, you can also
register helpers and extensions that will be used only within the
namespace.
Or change your application to the modular style:
require "sinatra/base"
class MyApp < Sinatra::Base
register Sinatra::Warden
# The rest of your modular application code goes here...
end

Sinatra Helper in External File gives LoadError

I'm trying to add a helper to connect to a mongo db to my modular Sinatra application
When I type foreman start in my console I get:
/home/sunny/Programs/landing_pages/app.rb:17:in `block in <class:LandingPages>': undefined local variable or method `connect' for LandingPages:Class (NameError)
My app.rb file looks like this:
require 'sinatra/base'
require 'sinatra/partial'
require 'sinatra/db_helper'
require 'bundler/setup'
require 'mongo'
class LandingPages < Sinatra::Base
helpers Sinatra::DbHelper
configure do
$collection = connect
end
end
My ./lib/sinatra/db_helper.rb looks like this:
require 'sinatra/base'
module Sinatra
module DbHelper
def connect
conn = Mongo::Connection.new("localhost")
db = conn.db("leads")
db.collection("laws")
end
end
helpers DbHelper
end
My config.ru looks like this:
require './app'
run LandingPages
I thought I was following the instructions correctly on:
http://www.sinatrarb.com/extensions.html
but I'm not totally sure. I'm not making a gem but just a sinatra app so maybe my directory hierarchy isn't correct. I don't have a rake file or a gem spec. Do I need them?
Some googling also found this:
sinatra helper in external file
Dave Sag answers my question perfectly but I can't get it work.
This comes about because of the scope of methods created through the helpers is on the sinatra application instance, since it calls ruby's include under the hood. So this would work:
get '/some/route' do
db = connect
# do something else ...
end
But the configure block has a class scope, so it can be used for configuring the application as a whole. So to make this work, you can define the method as:
module Sinatra
module DbHelper
def self.connect
conn = Mongo::Connection.new("localhost")
db = conn.db("leads")
db.collection("laws")
end
end
end
which could then be called via: $collection = Sinatra::DbHelper.connect or perhaps more favoured, you could call register instead of helpers. register calls extend under the hood, so you end up with class level methods (if you extend a class, anyway). You could then make the configure block as so:
configure do |app|
$collection = app.connect
end
You could also do all of this in an registered method on the DbHelpers module. See the example in the documentation for how this might work.

Resources