I'm trying to add the sinatra-authentication gem to a Sinatra app, and while it's in there and doing part of its thing, for some reason the routes are seemingly not getting added. The code basics:
require 'sinatra'
require 'digest/sha1'
require 'rack-flash'
require 'mongo_mapper'
require 'sinatra-authentication'
MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, :pool_size => 5, :pool_timeout => 5)
MongoMapper.database = 'cms'
module CmsMod
class CmsApp < Sinatra::Base
use Rack::Session::Cookie, :secret => 'something secret'
use Rack::Flash
get '/' do
#redirect to('/list') # commented out for testing
end
get '/private' do
login_required
'Protected Page'
end
And then the rest of things. The symptoms are that pointing the browser to my normal routes works fine. Going to '/private' does the redirect to '/login' properly, but I get the old "Sinatra doesn't know this ditty" message; same if I try to visit '/login' directly. I tried using 'binding.pry' to inspect things inside a get block and from what I could tell the routes aren't there. Any ideas about what could cause this would be really appreciated.
Having looked at the library's source, it's written as an extension but the examples and docs don't mention how the extension is registered. Try this:
module CmsMod
class CmsApp < Sinatra::Base
register Sinatra::SinatraAuthentication # <= this is the missing magic line.
then the routes should appear. As an aside, I'd also suggest using the encrypted_cookie gem.
use Rack::Session::Cookie, :secret => 'something secret'
becomes:
use Rack::Session::EncryptedCookie, :secret => 'something secret'
seems like it requires 'haml' gem as well, so if you are not using haml (like I'm using slim), you should include haml in your project for it to work, what a pain!!
Also remember to set layout in your view, because by default it will be looking for views/layout.haml
Related
Maybe I'm stupid but Rails provides this nifty syntax for generating URL's like so:
url_for([user, comment]) # => /users/1/comment/1
Passing :edit allows me to create something like this:
url_for([:edit, user, comment]) # => /users/1/comment/1/edit
but is there some way to do following?
url_for([:new, user, comments]) # => NoMethodError: undefined method `new_user_comments_url'
UPDATE: Added more information.
My routes.rb:
resources :users do
resources :comments
end
resources :posts do
resources :comments
end
My problem here is, that I can't use Rails auto-generated url helper (user_comments_url), because I'm sharing the views for both user comments and post comments.
There are two workarounds (but no one feels like the "Rails"-way) for my problem:
Adding logic to the view, e.g. some if conditions.
Defining my own url helpers like new_parent_comment(user_or_blog).
Ok, found a solution, but I'm not sure if this is the intended one:
url_for([:new, user, :comment]) # => '/users/1/comments/new'
url_for([:new, post, :comment]) # => '/posts/1/comments/new'
Stuck with the same problem, and found next solution (tested on Rails 5.2):
url_for([user, Comment, action: :new])
where Comment model class name.
By the way, action also could be :edit.
According to the Rails Docs url_for uses the class name of the object passed to generate the RESTful route. It also states that with nested routes it can not make this assumption correctly:
If you have a nested route, such as admin_workshop_path you’ll have to call that explicitly (it’s impossible for url_for to guess that route).
I would suggest using a named route here something like new_user_comment_path(). I am assuming you have set up your routes.rb something like:
resources :users do
resources :comments do
end
end
Additionally you can run rake routes to print out the proper names for all your routes.
Hope this helps,
/Salernost
Could this simply be a typo? I think the last line should read comment, not comments:
url_for([:new, user, comment])
(Assuming your comment variable has been defined.)
i would like to add a route that is only available in test environment, so i would prefer not to pollute routes.rb file. i cannot seem to find a working way to add a route dynamically after original routes were drawn. i tried this https://gist.github.com/1351762 but that didn't quite work
How can I add a new route after routes.rb has already loaded and processed all the routes?
The with_routing test helper redefines routes within a block.
with_routing do |map|
map.draw do
resources :test, only: [:show]
end
get :show
assert assigns(:test)
end
After some tries and errors, I found that:
Rails.application.routes.eval_block(Proc.new do
get "/backdoor", :to => "backdoors#backdoor"
end)
I have a double namespace situation, where my controllers look like this:
CandidateController
Candidate::PerformanceController
Candidate::Performance::ReviewController
In Rails 2, I was able to use redirect_to from the Candidate::Performance::ReviewController controller in order to redirect to an action in the CandidateController, like so:
class Candidate::Performance::ReviewController < ApplicationController
before_filter :ensure_manager
# ...
def ensure_manager
if !current_user.manager?
flash[:warning] = t(:must_be_manager)
redirect_to :controller => '/candidate', :action => :index
end
end
end
The / in controller => '/candidate' would allow Rails to redirect from app.com/performance/reviews to app.com/candidate.
However, this seems to not work the same in Rails 3.1. Instead, my redirect_to goes to app.com/candidate//candidate. What is the correct way to specify a "absolute" controller within a redirect_to hash (ie. without using a path helper)?
Update: I know this would be infinitely easier if I just use named route helpers (ie. candidate_path). Unfortunately, there is a lot of legacy code in our codebase which doesn't use RESTful routing and instead uses the default "catch-all" route; ie. we have a lot of actions with no named route to fallback on.
I wonder if something else is wrong. In the doc:
In particular, a leading slash ensures no namespace is assumed. Thus,
while url_for :controller => ‘users‘ may resolve to
Admin::UsersController if the current controller lives under that
module, url_for :controller => ’/users‘ ensures you link to
::UsersController no matter what.
And I don't think it changed...
Also, shouldn't the catch-all routes be after the default routes in your config?
I think that redirect_to :controller => ... uses url_for to build the url, so in the end, if your custom routes catches /candidates, I don't really see the difference.
Some people have the same problem: https://github.com/rails/rails/issues/2575
Patching actionpack/lib/action_dispatch/routing/route_set.rb line 434
as follows fixes this: if !named_route && different_controller? &&
!controller.starts_with?('/')
If anyone else runs into this problem, it seems to be a known issue (unsure whether they consider it a bug or not, given the lack of response on the issue page from anyone working on Rails).
Until they patch it (assuming they do), I've added the following little monkey patch into an initializer, based on the code given in the original post of that issue:
module ActionDispatch
module Routing
class RouteSet
class Generator
def use_relative_controller_with_absolute_paths!
return if controller.starts_with?('/')
use_relative_controller_without_absolute_paths!
end
alias_method_chain :use_relative_controller!, :absolute_paths
end
end
end
end
Hope this can help someone else!
Update: It seems that this was fixed in Rails here.
I'm writing a rails 3 railtie which defines some view helpers. Now I wonder how to spec the view helper methods because I cannot instantiate a module. I already searched and read a lot, but I just couldnt get it working.
view_helper_spec.rb
require 'spec_helper'
module MyRailtie
describe ViewHelper, :type => :helper do
describe "style_tag" do
it "should return a style tag with inline css" do
helper.style_tag("body{background:#ff0}").should ==
body{background:#ff0}
EOT
end
end
end
end
It always complains that "helper" is not defined. It seems that :type => :helper doesn't to anything.
The gemspec requires the rspec and the rspec-rails gems in development/ test mode.
I think I found the solution (it's painfully obvious once you think about it). Just stick this at the top of your spec:
require 'action_view'
require 'active_support'
include ViewHelper
include ActionView::Helpers
I fixed RoutingError in rails 3 using this link. I wanted to redirect users to root page so I added:
match '*a', :to => 'homes#index'
to my routes.rb.
Question is: can I define flash[:error] message in this 'match' line to be displayed on target page?
Regards,
Mateusz
This is similar to Redirect and raise flash message when catch-all in routes
But I did run into this problem and it was giving me an issue because I was using MATCH and when I used GET, the alert wouldn't flash. Eventually I found a working solution using the thread above and applying GET in another manner.
match '*path' => redirect{ |p, req| req.flash[:alert] = "The page you requested is not valid."; '/' }, via: [:get]
This is what I ultimately came up with, via: [:get] being key to making everything work.
And remember to place such code at the end of your routes.rb