Allow users to edit their account without providing a password | Rails4 - ruby-on-rails

In Rails 3 it worked just fine, but with my new Rails4 Appp i don't know whats the problem.
The Guide on the Devise GitHub Page
My Registrations Controller
def update
# required for settings form to submit when password is left blank
if params[:user][:password].blank?
params[:user].delete("password")
params[:user].delete("password_confirmation")
end
#user = User.find(current_user.id)
if #user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
set_flash_message :notice, :updated
# Sign in the user bypassing validation in case his password changed
sign_in #user, :bypass => true
redirect_to after_update_path_for(#user)
else
render "edit"
end
end
My Application Controller
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:name, :first_name, :user_name, :email, :password, :password_confirmation, :provider, :uid)
end
devise_parameter_sanitizer.for(:account_update) do |u|
u.permit(:name, :email, :password, :password_confirmation, :first_name, :last_name,
:user_name, :avatar, :profile_cover, :facebook_link,
:twitter_link, :instagram_link, :status)
end
end
I added the controller to my Routes
:registrations => "registrations"
And i Changed the update calls using the appropriate method below:
#user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
But i'm getting a NoMethodError in RegistrationsController#update Error.

I don't know yet if this is a good practice but i changed in my RegistrationsController the update action to
#user.update_attributes(account_update_params)

Related

ActiveAdmin does not save attributes not coming from params

While creating an active admin record, am trying to save an attribute (role_type) which does not come from params.
However, the attribute does not get saved in creation.
I have added it to permit_params.
permit_params :email, :password, :password_confirmation, :phone_no, :name, :role_type, role_ids: []
controller do
def create
user = User.create(name: params[:user][:name], email: params[:user][:email], password: SecureRandom.hex, role_type: "employee")
flash[:notice] = "User Created"
redirect_to admin_user_path(user)
end
end
If you want to combine a params hash with some attributes that you assign manually the cleanest way is by using a block
permit_params :email, :password, :password_confirmation, :phone_no, :name, :role_type, role_ids: []
controller do
def create
user = User.create(permitted_params[:user]) do |u|
u.password = SecureRandom.hex
end
flash[:notice] = "User Created"
redirect_to admin_user_path(user)
end
end
However your password encryption scheme is very naive - I would recommend you use ActiveModel::SecurePassword instead of trying to reinvent the password encryption wheel and creating a insecure authentication system.
Another major issue is that you are not actually checking if the user is created!
permit_params :email, :password, :password_confirmation, :phone_no, :name, :role_type, role_ids: []
controller do
def create
user = User.new(permitted_params[:user]) do |u|
u.password = SecureRandom.hex
end
if user.save
flash[:notice] = "User Created"
redirect_to admin_user_path(user)
else
render :new
end
end
end

Rails 4 Devise Non-Lazy Function Overloading

I have two devise models- Worker and User. The worker signup requires additional attributes not specific to user.
I was running my user signup through the application controller
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :password, :email, :firstName, :lastName, :dateofBirth, :address1, :address2, :city, :state, :zip)}
end
However, when I added my worker sign up, I decided to go the nonlazy way, created my Worker controller via
rails generate devise:controllers Worker
And proceeded to the registration controller in worker. There I un-hashed the before-filter and added a params filter after searching Google and StackOflow to figure out how to do this. Also went into the Github devise source code and copied and pasted their create code in their registration controller. My controller looks like this:
class Workers::RegistrationsController < Devise::RegistrationsController
before_filter :configure_sign_up_params, only: [:create]
def create
build_resource(registration_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
set_minimum_password_length
respond_with resource
end
#super
end
protected
def registration_params
params.require(:worker).permit(:username, :password, :email, :firstname, :lastname, :address1, :address2, :city, :state, :zip)
end
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:username, :password, :email, :firstname, :lastname, :address1, :address2, :city, :state, :zip)}
end
end
end
The data still shows up as nil on my console. Why is the data not saving and how do I get the data to save?
OK for anyone who finds and can understand this- the answer is STI.
http://adamrobbie.me/blog/2013-3-29-sti-with-rails-40-beta-and-devise

forgot password using devise rails

I am using devise for user in my rails application
When i click on forgot password than it send mail to user for reset password instruction.
but when i click on that password reset link in mail it redirect to my custom user controller which i create for user edit profile...
how to call devise password edit method
below is my controller/users.
class UsersController < ApplicationController
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:notice] = "Profile successfully updated"
redirect_to authenticated_root_path
else
render 'edit'
end
end
def change_password
#user = User.find(current_user.id)
end
private
def user_params
params.require(:user).permit(:email, :first_name, :last_name,
:dob, :address, :zip_code, :about_me, :country_id, :state_id,
:city_id, :phone_no, :status, :profile_pic, :gender,
:password, :password_confirmation)
end
end
Use this path for password reset for devise:
edit_user_registration_path

update_resource_params gives Unpermitted parameters error - Devise Invitable

I am trying to implement invitation on existing users in my app, using Devise Invitable.
At first glance this fails, because Devise Invitable is best used on new users - i.e. non-registered.
But this is what my User::InvitationsController looks like (truncated for brevity):
class Users::InvitationsController < Devise::InvitationsController
include ApplicationHelper
before_filter :configure_permitted_parameters, if: :devise_controller?
before_filter :update_sanitized_params, only: :update
# PUT /resource/invitation
def create
invited_user = User.where(email: params[:user][:email])
if !invited_user.empty?
invitation_token = Devise.token_generator.digest(resource_class, :invitation_token, update_resource_params[:invitation_token])
self.resource = resource_class.where(invitation_token: invitation_token).first
family_tree = self.resource.invited_by.family_tree
family_tree.memberships.create(:user_id => user.id, relation: update_resource_params[:relation])
resource.create_membership_both_ways(params[:user][:invitation_token], params[:user][:relation])
resource.skip_password = true
resource.update_attributes update_resource_params.except(:invitation_token)
redirect_to my_tree_path
else
super
end
end
protected
def update_sanitized_params
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:name, :password, :password_confirmation, :invitation_token, :invitation_relation,:avatar, :avatar_cache, :relation)
end
end
def update_resource_params
devise_parameter_sanitizer.sanitize(:accept_invitation) do |u|
u.permit(:email)
end
end
end
When I use pry for debugging, this is what happens when I poke around invitation_token:
[1] pry(#<Users::InvitationsController>)> invitation_token
=> false
[2] pry(#<Users::InvitationsController>)> update_resource_params
Unpermitted parameters: email
=> {"name"=>"", "invitation_relation"=>"uncle"}
Thoughts on what may be causing this, or how I can get rid of this unpermitted paramters :email problem?
Edit 1
These are the relevant routes:
devise_for :users, :controllers => { :invitations => 'users/invitations', :confirmations => 'confirmations' }
devise_scope :user do
post "users/invitation/sign_in" => "users/invitations#invite_sign_in"
end
Edit 2
In my application_controller.rb I have a method that I added :email and it seems to have stopped that error:
def configure_permitted_parameters
# Once I added :email to this method, it stopped throwing the unpermitted error
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:name, :email, :last_name, :invitation_relation)
end
end
When using Devise and configuring permitted_params it is best to do this in the application controller,
you can do it one of two ways
def configure_permitted_parameters
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:name, :email, :last_name, :invitation_relation)
end
end
OR
def configure_permitted_params
devise_parameter_sanitizer.for(:accept_invitation) << [:name, :email, :last_name, :invitation_relation]
end

Rails Scaffold destroy not working as expected

I was adding uniqueness validation to the model in charge of user registration. The username should be uniqueness.
I created a user when testing some days ago, lets call it "example-guy". Then I deleted him from the scaffolding user interface and now when trying to register a new user as "example-guy", it returns that the name has already been taken.
So how can I fix this from the DB without reverting to its "birth-state" and modify the controller to actually destroy the table entry?
Or maybe Rails is keeping track of what was writed to DB, even after destruction?
Im using omniauth-identity, the user model:
class User < ActiveRecord::Base
attr_accessible :name, :provider, :uid, :email
# This is a class method, callable from SessionsController
# hence the "User."
def User.create_with_omniauth(auth)
user = User.new()
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["info"]["name"]
# ADD EMAIL
user.email = auth["info"]["email"]
user.save
return user
end
end
User controller's destroy function:
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
end
Validations are made trought "Identity" model inherited from omniauth's active record:
class Identity < OmniAuth::Identity::Models::ActiveRecord
attr_accessible :email, :name, :password_digest, :password, :password_confirmation
#attr_accessible :email, :name, :password_digest :password, :password confirmation
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :in => 6..24
validates_format_of :name, :with => /^[a-z]+$/
validate :name_blacklist
validates_uniqueness_of :email, :case_sensitive => false
validates_format_of :email,
:with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
:message => "doesn't look like a proper email address"
#validates_presence_of :password, on: :create
#validates_presence_of :password_confirmation
validates_length_of :password, :in => 6..24
def name_blacklist
unless self.name.blank? then
case self.name
when "user", "photo", "photos",
"application", "sessions",
"identities", "home"
self.errors.add(:name, "prohibited")
end
end
end
end
Identities controllar manage registration form sent to omniauth and calling new.html.erb:
class IdentitiesController < ApplicationController
def new
#identity = env['omniauth.identity']
end
end
Thanks in advance.
I'm not entirely sure what caused the problem, but I came across a similar problem but with email addresses with a Devise based user.
I was wanting to re-use the same email on a different user. I changed the original user to a different email, but when I then tried to update the second user with the "now unique" email, it failed the unique validation.
A query for users with that email returned nothing.
It seemed to be cache-related to the uniqueness constraint, as restarting the server, after deleting the email address, fixed the problem.

Resources