Rails 4 updating field in devise registrations controller before saving user - ruby-on-rails

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

Related

CanCanCan: How to handle an object that is nil in Ability model?

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

Rails 5: devise invitable add custom fields

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

uninitialized constant UController::User_param

I am making a basic account setup and to try to learn how the database stuff works. I have been running into this error constantly, and I have no idea how to make it disappear. I have my stuff named as U, so the URL will be easier to type a username like Reddit has it example.com/u/username
The Error is uninitialized constant UController::User_param
It highlights this code: #user = U.new(User_param)
Controller:
class UController < ApplicationController
def index
#users = U.all
end
def show
end
def create
#user = U.new(User_param)
if #user.save
redirect_to :action => 'list'
else
#user = U.all
render :action => 'new'
end
end
def User_param
params.require(:Us).permit(:id, :email, :password, :created_at, :updated_at)
end
def new
#user = U.new
end
def edit
end
end
Routes:
resources :u
U Model:
class U < ActiveRecord::Base
end
In Rails you don't capitalize methods, only constants and classes. change User_param to user_params along with the method and that should work. I made params plural since it is clearer and easier to understand
Also, change the user_param method to this:
def user_params
params.require(:u).permit(:id, :email, :password, :created_at, :updated_at)
end
The .require(:u) doesn't need to be plural as you had it.

helper functions are not working

users_controller.rb
class UsersController < ApplicationController
include UsersHelper
def new
#user = User.new
end
def create
if isUsernameTaken?
render 'new'
elsif isEmailTaken?
render 'new'
else
#user = User.new(user_params)
if #user.save
else
render 'new'
end
end
end
private
def user_params
params.require(:user).permit(:username,:email,:password,:password_confirmation)
end
end
users_helper.rb
module UsersHelper
def isUsernameTaken?
!(User.find_by(username: params[:username]).nil?)
end
def isEmailTaken?
!(User.find_by(email: params[:email]).nil?)
end
end
The problem is isUsernameTaken? or isEmailTaken? never gets executed and always the else part gets executed even if I give same username again. Why is this happening?
This is because params[:username] and params[:email] are always blank in your controller. They should be params[:user][:username] or user_params[:username].
Anyway, those kind of checks belongs to the model, not the controller and there already are validators to do exactly what you want:
class User < ActiveRecord::Base
validates :email, :username, uniqueness: true
end

Rails- Loading user's page 'Couldn't find User with id=id'

What I am trying to do is to go to user's page after signin/up. On the error page is written that the error is in users_controller. So this is my user controller:
class UsersController < ApplicationController
def show
#user = User.find([:id])
end
def index
end
def new
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
# Handle a successful save.
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
Your show method should be:
def show
#user = User.find( params[:id] )
end
And not [:id] alone. You're accessing the :id key at the params hash object.

Resources