Thoughtbot's Clearance gem, overriding url_after_destroy - ruby-on-rails

I was able to successfully override url_after_create, but my url_after_destroy is being ignored.
What am I messing up?
routes:
map.resource :session,
:controller => 'sessions',
:only => [:new, :create, :destroy]
my Sessions controller:
class SessionsController < Clearance::SessionsController
private
def url_after_create
puts "************after create****************" #called on sign in
end
def url_after_destroy
puts "************after destroy****************" #never called
end
end

The docs say:
You may also need to add code such as
the following to your routes.rb:
map.sign_out 'sign_out',
:controller => 'sessions',
:action => 'destroy',
:method => :delete
That's what I'm missing. Perhaps 'may' is not the best choice of verb for documentation.

Related

how to properly display image from database in ruby on rails

Am new to ruby on rails. Here Am trying to display image from database. To this effect, I leverage solution found here
link. but when I run my script it displays error
No route matches {:action=>"show", :controller=>"attachments_controller", :id=>17}
Please what am I doing wrong with the route.
Routes
Rails.application.routes.draw do
resources :attachments, only: [:index, :new, :create, :destroy]
root "attachments#create"
get "attachments/show" => "attachments#show"
end
attachments_controller
class AttachmentsController < ApplicationController
def show
#attachment = Attachment.find(params[:id])
send_data #attachment.data, :filename => #attachment.filename, :type => #attachment.content_type
end
end
show.html
<%= image_tag url_for(:controller => "attachments_controller", :action => "show", :id => #attachment.id) %>
The error message you provided states:
No route matches {:action=>"show", :controller=>"attachments_controller", :id=>17}
The routes file you provided shows the routes you created:
resources :attachments, only: [:index, :new, :create, :destroy]
get "attachments/show" => "attachments#show"
Running rake routes will show that you've created the 4 routes in the first line, plus a route that responds to 'attachments/show'. If you really want to define the route like this, you should try:
get "attachments/:id", to: "attachments/show"
Your first route only responds to the word show, and would supply no params. The last route will take whatever comes after attachments, and pass it to the show action of the attachments controller as a paramater called 'id'.
Of course the easiest way to do all of that is to get rid of it all, and simply change the first route to:
resources :attachments, only: [:index, :new, :create, :destroy, :show]
Letting rails create the show route for you is exactly the same as manually defining it, and obviously reads a lot better
change
<%= image_tag url_for(:controller => "attachments_controller", :action => "show", :id => #attachment.id) %>
to
<%= image_tag url_for(:controller => "attachments", :action => "show", :id => #attachment.id) %>

Cannot rake migration for my ruby project

When I try to rake a migration for my ruby project, it gives me an error "'API::sessions' is not a supported controller name". Does anyone know how to solve this problem? The following code is from my routes.rb file and sessions_controller.rb file.
Rails.application.routes.draw do
get 'projects/:id', to: 'projects#show'
get 'projects', to: 'projects#index'
get 'welcome/index'
root 'welcome#index'
match '/login', to: 'sessions#new', via: :get
match '/login_create', to: 'sessions#create', via: :post
resources :users
scope :format => true, :constraints => { :format => 'json' } do
post "/api/login" => "API::sessions#create"
delete "/api/logout" => "API::sessions#destroy"
end
end
class API::SessionsController < API::ApiController
skip_before_action :require_login, only: [:create], raise: false
def create
if user = User.valid_login?(params[:email], params[:password])
allow_token_to_be_used_only_once_for(user)
send_auth_token_for_valid_login_of(user)
else
render_unauthorized("Error with your login or password")
end
end
def destroy
logout
head :ok
end
private
def send_auth_token_for_valid_login_of(user)
render json: { token: user.token }
end
def allow_token_to_be_used_only_once_for(user)
user.regenerate_token
end
def logout
current_user.invalidate_token
end
end
The error appears when you define the post and delete routes within the format scope, to tell Rails which controller and action/method use for the URI being defined.
To refer then the controller name and action use the lowercase name followed by a slash, instead the uppercase controller name and colons ::, like:
post '/api/login' => 'api/sessions#create'
delete '/api/logout' => 'api/sessions#destroy'

No route matches for devise sessions destroy path

I have installed devise to my rails app and was originally able to sign out using <%= link_to('Logout', destroy_user_session_path) %>
However, somewhere along the line after adding more code and a few gems (paperclip, act_as_votable, social_share_button) I was not able to use the same link. When I click the link_to I receive the error
No route matches [GET] "/users/sign_out"
I have also tried adding config.sign_out_via = :get to my devise.rb file but still got the same error. What have I done wrong?
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'users/registrations', sessions: 'users/sessions' }
root to:'ideas#index'
get "/page", to: 'pages#index'
resources :ideas, only: [:index, :show, :create, :destroy, :new] do
member do
put "like", to: "ideas#upvote"
put "dislike", to: "ideas#downvote"
end
end
resources :comments, only: [:create]
end
sessions controller
class Users::SessionsController < Devise::SessionsController
def new
super
end
def create
super
end
def destroy
super
end
end
I believe <%= link_to 'Logout', destroy_user_session_path, method: :delete %> is what you're looking for

Routing to delete in my restful web service is not working

I am having an problem routing to my delete method on my restful web service for permissions.
My routes are set up as follows :
namespace :service do
namespace :v1 do
resources :surveys do
resources :permissions, only: [:index, :create, :delete, :update]
end
end
end
The following spec passes
it "routes toya expected controller method" do
{:get => 'service/v1/surveys/3/permissions'}.should route_to(controller: 'service/v1/permissions', action: 'index', :survey_id => "3")
end
This spec fails
describe 'DELETE :destroy' do
it "routes to expected controller method" do
{:delete => 'service/v1/surveys/3/permissions'}.should route_to(controller: 'service/v1/permissions', action: 'destroy', :survey_id => "3")
end
end
The snippet from my controller is as follows
module Service
module V1
class PermissionsController < ApplicationController
before_filter :authenticate_user!, :only => []
def index
render :json => permissions, :each_serializer => Service::V1::PermissionSerializer
end
def destroy
debugger
# cant route to here
a = 1
end
end
end
end
Any suggestions ? I am slightly confused between destroy and delete, I think that might be the source of my problem
You need to pass permission id as well like:-
{:delete => 'service/v1/surveys/3/permissions/permission_id'}.should route_to(controller: 'service/v1/permissions', action: 'destroy', :survey_id => "3", :id => "permission_id")

No Route Matches ... Rails Engine

So I keep getting the error:
No route matches {:action=>"create", :controller=>"xaaron/api_keys"}
Which is thrown in the test:
it "should not create an api key for those not logged in" do
post :create
expect(response).to redirect_to xaaron.login_path
end
when I go to spec/dummy and run the rake routes command I see:
api_keys GET /api_keys(.:format) xaaron/api_keys#index
POST /api_keys(.:format) xaaron/api_keys#create
new_api_key GET /api_keys/new(.:format) xaaron/api_keys#new
edit_api_key GET /api_keys/:id/edit(.:format) xaaron/api_keys#edit
api_key GET /api_keys/:id(.:format) xaaron/api_keys#show
PATCH /api_keys/:id(.:format) xaaron/api_keys#update
PUT /api_keys/:id(.:format) xaaron/api_keys#update
DELETE /api_keys/:id(.:format) xaaron/api_keys#destroy
Which shows that yes this route does exist. My routes file for this engine looks like:
Xaaron::Engine.routes.draw do
get 'login' => 'sessions#new', :as => 'login'
get 'logout' => 'sessions#destroy', :as => 'logout'
get 'signup' => 'users#new', :as => 'signup'
get 'permission_denied' => 'error#denied', :as => 'permission_denied'
get 'record_not_found' => 'error#error', :as => 'record_not_found'
get 'password_reset' => 'password_resets#edit', :as => 'rest_user_password'
resource :error, controller: 'error'
resources :users
resources :api_keys
resources :sessions
resources :roles
resources :password_resets
end
What am I missing?
update
For those of you curious how I am getting these routes, its because the dummy app's routes file is set up (by default) as such:
Rails.application.routes.draw do
mount Xaaron::Engine => "/xaaron"
end
Update II
I have been reading this api docs on how routing is done in engines and I believe the way I have done this is correct, how ever the controller is defined as such:
module Xaaron
class ApiKeysController < ActionController::Base
before_action :authenticate_user!
def index
#api_key = Xaaron::ApiKey.where(:user_id => current_user.id)
end
def create
#api_key = Xaaron::ApiKey.new(:user_id => current_user.id, :api_key => SecureRandom.hex(16))
create_api_key(#api_key)
end
def destroy
Xaaron::ApiKey.find(params[:id]).destroy
flash[:notice] = 'Api Key has been deleted.'
redirect_to xarron.api_keys_path
end
end
end
You need to tell your spec you are using the engine routes:
describe ApiKeysController do
routes { Xaaron::Engine.routes }
it "should not create an api key for those not logged in" do
post :create
expect(response).to redirect_to xaaron.login_path
end
end

Resources