I've seen this posted before but haven't found a solution that works for me.
I have tried following the Devise Wiki and have tried the code suggested by others to add to the controller:
Editing Users With Devise and Omniauth
[Rails]update_without_password does't update user info
https://github.com/plataformatec/devise/issues/1620
Problem is that a user signs up via our Twitter Omniauth is unable to update their account info because Devise prompts them for their 'current password' to make changes. Emailing the user their random generated password isn't an option.
What i want to do -
I want to override the Devise controller's 'update' method so that it recognises a Twitter user editing their details for the first time and allows them to skip the 'current password' validation. We assign twitter users a standard email address that can be the variable it checks for. They won't be able to submit the from without changing it.
Still the problem -
I've tried different code blocks in the Registration Controller, but I still am getting redirected back to the from with an error that the current password is incorrect. I'm not even entering into a binding.pry , so it looks like the method is not even being read?
I have tried removing the form input for 'current password' completely, and passing it in hidden with a default value.
thank you for your help!
Routes
Rails.application.routes.draw do
ActiveAdmin.routes(self)
# devise_for :users,
devise_for :users, controllers: { registrations: 'registrations' },
controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
scope '(:locale)', locale: /en|ca|es/ do
resources :politicians
resources :posts do
resources :comments, only:[:new, :create, :edit, :update, :destroy]
member do
put "like", to: "posts#upvote"
put "dislike", to: "posts#downvote"
end
end
get "/about" => "pages#about_us"
root to: 'pages#home'
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Registrations_Controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
binding.pry
if current_user.email.include?("email.com")
params.delete("current_password")
resource.update_without_password(params)
else
resource.update_with_password(params)
end
end
end
You'll want to create a method similar to this one in your registration's controller:
def update_resource(resource, params)
resource.update_without_password(params)
end
Devise offers a very nice, in-depth wiki article for allowing users to update their account information without entering their password here.
Related
I'm new to Rails & I have a page where the user can cancel their account using button_to. However, how can I redirect the user to another page? For example, I would want to redirect to a post-cancellation page saying "goodbye" upon deletion of their account.
I tried looking to see if there was an after_user_deletion devise method to override but there is not.
Here is what I have in the edit view under registrations from Devise.
<div id="modal">
<p>Are you sure you want to cancel?</p>
<%= button_to "Yes", registration_path(resource_name), method: :delete%>
<button>No</button>
</div>
Im not sure if it's necessary to make another controller but I made a cancellation controller.
class CancellationController < ApplicationController
before_action :authenticate_user!
def cancel
end
end
Here is what I have in routes.rb
Rails.application.routes.draw do
devise_for :users
root to: 'dashboard#index'
devise_scope :user do
get 'cancel' => 'cancellation#cancel'
end
end
Here is the contents of rake routes:
RakeRoutes
You need to override the redirect on the devise registration controller:
# config/routes.rb
devise_for :users, controllers: { registrations: 'registrations' }
This will point to your controllers folder now! So you need to create your own devise controller:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
# DELETE /resource
def destroy
# your own logic here, so you can redirect it after
end
def cancel
expire_data_after_sign_in!
redirect_to here_your_url
end
end
Note: You are using the DELETE on your button, that triggers the destroy not the cancel, you can check the devise controller here.
I have used devise numerous times but currently facing an issue at the moment.
I used this devise wiki to set up devise with multiple user models which i have done multiple times. https://github.com/heartcombo/devise/wiki/How-to-Setup-Multiple-Devise-User-Models
In my admins_controller.rb i have the following code
class AdminsController < ApplicationController
before_action :authenticate_admin!
end
My routes.rb
Rails.application.routes.draw do
devise_for :admins, path: 'admins', controllers: {sessions: "admins/sessions", registrations: "admins/registrations"}
namespace :admins do
root "dashboards#index"
end
end
Everything else works well but after i try to sign in as an admin, it should redirect to my admins root but i always get this error
You need to sign in or sign up before continuing.
But when i do admin_signed_in? or current_admin. I get true and my admin record accordingly. Which means the admin is already signed in.
When i comment the before_action code, then it works perfectly.
Currently stuck and cannot think of why and how to solve this issue.
In my application I am using the Devise authentication gem which works really well. I also have built a static landing page which I currently have in the /public directory.
I can of course browser to localhost:3000/landing and see the page (as per the route below) but what I'm trying to achieve but cannot seem to figure out is how to setup my routes.rb file so that the landing.html file is the root, but when a user is logged in, their root becomes companies#index.
Here is my routes.rb file
Rails.application.routes.draw do
devise_for :users
get 'dashboard/index'
get '/landing', :to => redirect('/landing.html')
root 'companies#index'
resources :companies do
resources :shareholders
resources :captables do
post :subscribe_to_captable
resources :events do
post :lock_event
post :unlock_event
resources :transactions
end
end
end
end
Here is my application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
One way is to put the redirect inside your CompaniesController.rb index method do this.
CompanesController.rb (or whatever it is called)
def index
unless user_signed_in?
redirect_to landing_pages_path (or whatever the name of the route is)
end
end
Then change the route in the routes.rb file.
get '/landing', to: 'companies#landing' * change companies here to the name of the controller holding the landing page's method if it is not in the companies controller.
struggling for a few hours on this one now. I have integrated the Devise gem into my Rails project after originally making my own auth system but I am facing an issue I can't understand.
When the user signs in the method:
def after_sign_in_path_for(resource_or_scope)
user = resource_or_scope
user_path(user.username)
end
Is triggered to redirect the user to their profile.
I have an edit user route which takes the user to a page in which they can edit their details and add a 'wanted item'. Two separate forms with two separate controllers and actions.
The 'add wanted item' method posts to a different controller that rendered the view called WantsController and adds a wanted item for the user through an association.
For some reason the after_sign_in_path_for method is called when submitting this form? It has nothing to do with signing in...
Here are my routes:
#users/auth
devise_for :users, :skip => [:sessions, :registrations]
devise_scope :user do
# registration
get "/signup", to: "users#new", as: :sign_up
post "/signup", to: "users#create", as: :sign_up_create
# account
get "/:username/account", to: "users#edit", as: :user_account
put "/users/:id", to: "users#update", as: :user_update
# shows
get "/:username", to: "users#show", as: :user
get "/:username/interests", to: "users#interests", as: :user_interests
get "/:username/offers", to: "users#offers", as: :user_offers
get "/:username/trades", to: "users#trades", as: :user_trades
# auth
post "/signin" => 'devise/sessions#create', as: :sign_in
delete "/signout", to: "devise/sessions#destroy", as: :sign_out
#wants
resources :wants, only: [:create, :destroy]
end
If I place the wants resource outside of the devise scope (which is where I expect it should go) I receive the following:
Could not find devise mapping for path "/wants"
What's happening here? Stumped!
Thanks.
Argh, silly mistake. Why is it after hours of struggling that when you post a question on Stack Overflow you figure it out after like 5 minutes?!
I had copied and pasted my RegistrationsController into the WantsController file to save typing the controller code but forgot to make it inherit from ApplicationController rather than Devise::RegistrationsController.
Lesson: Don't copy and paste!
I would like to create a new controller that will allow the admin user to edit models attached to users outside of rails admin. Here is a sample from my routes.rb:
devise_for :admins
mount RailsAdmin::Engine => '/admin', :as => 'rails_admin'
devise_for :dealers
devise_for :users
get "..." => "..."
etc
What do I need to do in both my controller and in routes.rb to make this possible? I'm fairly new to Rails. Thanks! I have a limited amount of time so making a rails-admin plugin is not feasible.
In your controller check if an admin is loged in using admin_signed_in?, and you can also access it by current_admin. So you just have to place conditions checking if it's and admin to enable or not those functionalities.
EDIT:
You can have something like this in your before_filter
before_filter :check_authentication
private
def check_authentication
authenticate_user! unless admin_signed_in?
end