I'm trying to add devise invitable to my new application. I found a lot of information on the internet but there doesn't seem to be a go to solution.
So the problems I'm facing are the following:
When a user invites someone the account gets created, while the standard email template generated by devise says 'Your account won't be created...'
When a user clicks the activation link he gets redirect to the edit page, but when they submit their information my columns :fullname, :terms_of_service are not saved.
Probably I'm missing something.
This is my invitations_controller
class InvitationsController < Devise::InvitationsController
def new
super
end
def create
User.invite!(invite_params, current_user)
redirect_to dashboard_path
end
def update
user = User.accept_invitation!(accept_invitation_params)
end
def edit
end
private
def invite_params
params.require(:user).permit(:email, :ivitation_token, :provider, :skip_invitation)
end
def accept_invitation_params
params.permit(:password, :password_confirmation, :invitation_token, :fullname, :terms_of_service)
end
end
My console output:
Processing by InvitationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"/PoYvD7be0xpE1yBGI2EsojBU62o8d+Kcx0B8LgZ7DJkrqz2lCGs1YrA8d5ziwOAVH68u+1ij7ZacecVmNfaUQ==", "user"=>{"invitation_token"=>"4a24a37282a3881a4d595f251ea4deca4d0c25cbb966d50d8d622941a55c1a4c", "fullname"=>"Arnas Klasauskas", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "terms_of_service"=>"1"}, "commit"=>"Einladen"}
Unpermitted parameters: :utf8, :_method, :authenticity_token, :user, :commit
No template found for InvitationsController#update, rendering head :no_content
My application_controller
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:email, :fullname, :terms_of_service])
end
So if you want to add custom parameters, you can simply add this line to your update method
User.accept_invitation!(update_resource_params)
Now you'll need to add the update_resource_params method to your invitations_controller with your custom fields:
def update_resource_params
params.require(:user).permit(:password, :password_confirmation, :invitation_token, :fullname, :terms_of_service)
end
This is called when creating invitation.
def invite_resource
User.invite!(invite_params)
end
This is called when accepting invitation.
def accept_resource
resource = resource_class.accept_invitation!(update_resource_params)
resource
end
This is where you customize your fields
def invite_params
params.require(:user).permit(:email, :invitation_token,...)
end
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:name, :time_zone, :terms_of_service,...])
end
Related
am gonna add the error and also my controller where i think its the source of the error
I have tried different solutions, but none of them worked, the weird thing, my code was working this morning, and this error only occurs after I added new tables to the database
this is my controller
class UsersController < ApplicationController
before_action :configure_permitted_parameters, if: :devise_controller?
def create
#user = User.new(user_params)
if #user.save
redirect_to root_path, notice: 'Sign up successful.'
else
render :new
end
end
def index
#users = User.all
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name, :password,
:password_confirmation])
end
end
and this is the error
Unpermitted parameters: :full_name, :password_confirmation. Context: { controller: Devise::SessionsController, action: new, request: #ActionDispatch::Request:0x00007fc5b5ca5a58, params: {"authenticity_token"=>"[FILTERED]", "user"=>{"full_name"=>"shaker abu drais", "email"=>"shaker_abady#yahoo.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up", "controller"=>"devise/sessions", "action"=>"create"} }
I have tried different solutions, but none of them worked, the weird thing, my code was working this morning, and this error only occurs after I added new tables to the database
What is it that you're actually trying to acheive here? If you're trying to just add additional attributes to the user registration then this code is just completely misguided.
You can whitelist additional attributes either through your ApplicationController which is the superclass for Devise's controllers:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name, :password,
:password_confirmation])
end
end
Or by creating a subclass of Devise::RegistrationsController and configuring the routes if you need to customize the workflow further:
devise_for :user, controllers: { registrations: 'my_registrations' }
class MyRegistrationsController < ::Devise::RegistrationsController
before_action :configure_permitted_parameters, if: :devise_controller?
# Don't clobber the entire `#create` method. Especially not without actually
# replicating its functionality
def create
super do |user|
# do something with the newly registered user
end
end
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name, :password,
:password_confirmation])
end
end
Note that I wouldn't call this controller UsersController. There is a reason why Devise choose the name Registrations - its because it differentiates between signing up and for example if users are created by an admin.
I have this controller:
class UsersController < ApplicationController
load_and_authorize_resource
def create
#user.save
respond_with #user
end
def update
#user.update user_params
respond_with #user
end
def destroy
#user.destroy
respond_with #user
end
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation,
:lock_version]
permitted_keys << :role if can? :edit_role, #user
params.require(:user).permit(permitted_keys)
end
end
In my ability model:
can :edit_role, User do |user|
user.new_record?
end
The problem is, that when creating a user (#new or #create action), #user is nil. So the role can't be set, as it will not be added to the permitted_keys on #create.
How can this be solved? I could change my controller to:
permitted_keys << :role if action_name == 'create'
But I don't like this, as the Ability can be tested much more easily than this.
Another workaround would be this:
permitted_keys << :role if can? :edit_role, #user || User.new
But this feels redundant.
Anybody has a better idea? And by the way - I'm quite surprised that passing nil as object to can? is allowed and doesn't raise an error. It seems that it doesn't even propagate to the actual configuration in Ability, as otherwise user.new_record? would raise a NoMethod error or similar.
The CanCan docs prescribe defining abilities with blocks a little differently than how you've done it. They suggest using a guard instead of a block for the case you described (when the instance is nil):
# don't do this
can :edit_role, User do |user|
user.new_record? # this won't be called for User.accessible_by(current_ability, :edit_role)
end
# do this
can :edit_role, User if user.new_record?
I'd try this. For other information and to see where I got this example, check these docs
It seems that using CanCanCan gem, the user_params method is called before the #user variable is created; this kind of makes sense, as user_params is needed to create the #user variable, or at least it is needed to assign the values from the form.
If CanCanCan would assign a new #user variable (of type User, of course) before assigning the values from the form, the following code would work on #create:
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation]
permitted_keys << :role if can? :edit_role, #user
permitted_keys << :disabled if can? :disable_user, #user
params.require(:user).permit permitted_keys
end
But as it doesn't do that apparently, the following workaround works for me:
private
def user_params
permitted_keys = [:name,
:email,
:password,
:password_confirmation]
auth_object = #user || User.new
permitted_keys << :role if can? :edit_role, auth_object
permitted_keys << :disabled if can? :disable_user, auth_object
params.require(:user).permit permitted_keys
end
I'm writing a custom sign-up devise controller, and I'm having trouble adding permitted params due to this error (this is the output from Rspec, but the same error happens manually):
Failure/Error: devise_parameter_sanitizer.permit(:sign_up, keys: [:nome, :password, :password_confirmation, :cnpj, :razao_social, :nome_fantasia, :email, :tipo_entidade_id])
NoMethodError:
undefined method `concat' for #<Proc:0x0055ca9fb2d850>
Did you mean? concern
The full controller:
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# POST /resource
def create
user_params = sign_up_params[:user_params]
entidade_params = sign_up_params[:entidade_params]
if !(User.exists?(email: user_params[:email]) || Entidade.exists?(cnpj: entidade_params[:cnpj]))
#entidade = Entidade.new(entidade_params)
#entidade.data_validade = 30.days.from_now
if #entidade.save
#user = User.new(user_params)
#user.entidade_id = #entidade.id
if #user.save
flash[:notice] = 'Usuario criado com sucesso.'
redirect_to root_path
end
end
end
end
protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:nome, :password, :password_confirmation, :cnpj, :razao_social, :nome_fantasia, :email, :tipo_entidade_id])
end
end
At first glance it seems like a bug in the gem, but no one seems to have this issue - google returns nothing relevant. Is this an error in my code?
I'm not sure if it was the case, but this error can occur if you duplicate the parameters sanitizer, like using it in users controller but also in application controller.
You can see a more detailed explanation here:
GitHub issue closed
I do not want to allow the user to update their :name. I found this question for Rails version 3 but the answer does not work for me. I am using Rails 4. I might just have the wrong syntax. I couldn't get #user.update_attributes(params[:user]) to work. Only: #user.update_attributes(user_params). I am not including :name on my edit form, but my understanding (??) is that a user could still pass it through the browser themselves and with my current code they could change :name.
class UsersController < ApplicationController
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
#user.update_attributes(user_params)
if #user.save
flash[:success] = "Profile updated"
redirect_to #user
else
flash[:danger] = "Profile update Unsuccessful"
redirect_to 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :email_confirmation, :password, :password_confirmation)
end
There's more than one way to assure users won't tamper with your business rules.
As you're already using Rails 4, you can take advantage of strong parameters to deny access to the :name attribute.
You can have different sets of rules for each controller action:
def create_user_params
params.require(:user).permit(:name,:email, :email_confirmation, :password, :password_confirmation)
end
def update_user_params
params.require(:user).permit(:email, :email_confirmation, :password, :password_confirmation)
end
#user.create(create_user_params)
#user.update_attributes(update_user_params)
drying up:
def allowed_update_attrs
[:email, :email_confirmation, :password, :password_confirmation]
end
def allowed_create_attrs
allowed_update_attrs + [:name]
end
def user_params
params.require(:user)
end
#user.create user_params.permit(*allowed_create_attrs)
#user.update_attributes user_params.permit(*allowed_update_attrs)
There are other ways of accomplishing the same thing like tapping into already permitted attributes, but this way seemed simpler.
I am trying to generate and save a random string of characters to a user field called railsid. I have overridden the registrations_controller.rb for the devise user. I would like this randomly generated string of characters to be saved into the user object when the object is created. When I go into the rails console to see if the user has a railsid saved, it returns nil.
registrations_controller.rb
class Lenders::RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params
def new
super
end
def create
#user = User.new(params[:user])
#user.railsid = '%010d' % rand(10 ** 10)
super
end
def edit
super
end
def update
super
end
def authenticate_scope!
send(:"authenticate_user!", :force => true)
self.resource = send(:"current_user")
end
private
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, :type, :confirmed_at, :first_name, :last_name, :railsid)}
end
def after_sign_up_path_for(resource)
root_path
end
end
Shortly after posting this I tried the update_attribute method and it worked perfectly.
def create
super
resource.update_attribute(:railsid, '%010d' % rand(10 ** 10))
end