I have a small rails app, but i'm having trouble getting some information that i'm trying to implement into the user to save. My app as of right now asks for a username and password for signing up. I did this by using the devise gem. However I want to also add an age check to the app, and this is where i've been running into problems.
My DB column is set at (in my schema)
t.date "birth_date"
My view is at
<%= f.input :birth_date, required: true, start_year:1900 %>
My controller has two parts to it:
def create
#user = current_user.build(user_params)
end
private
def user_params
params.require(:user).permit(:birth_date)
end
Whenever i try to log in and create a birth_date for my new user, in the console when I check, the birth_date is still set at nil. Would anyone know what i am missing with this? (I think i'm getting tripped up with Devise handling some things already)
Assuming you are trying to do input birth_date of the user as a part of sign_up process and using devise for this purpose you need to whitelist birth_date params explicitly.
Best way of doing that is using your own registerations_controller and inheriting it from devise
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: :create
before_action :configure_account_update_params, only: :update
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: [:birth_date])
end
# If you have extra params to permit, append them to the sanitizer.
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update, keys: [:bith_date])
end
end
#in routes.rb
devise_for :users, controllers: {registrations: "users/registrations"}
since you using devise, and additional field while register, I think you should overwrite devise, here is link for reference, create registration controller as follow
app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
super do
resource.birth_date = params[:birth_date]
resource.save
end
end
end
make sure you also have devise routes
app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Assuming this your UsersController, separate from Devise controllers, you just need to save it to db:
def create
#user = current_user.update(user_params)
end
But you might need to change the birthday in params (which is a string) to a date object first, depending on your column type.
Also you might consider moving this to #update as this is really more an #update action than #create.
Related
I want to permit :full_name parameter for my user model registration in devise, and I always getting Unpermitted parameter: :full_name as response for Users::RegistrationsController#create action
I have tried several ways as I show you next:
1. Application controller (option 1)
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
case params[:action]
when 'create'
devise_parameter_sanitizer.permit(:sign_up, keys: %i[full_name])
when 'update'
...
end
end
end
Result => Unpermitted parameter: :full_name
2. Registration controller (option 2)
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: :create
protected
def configure_sign_up_params
params.require(:user).permit(%i[full_name])
end
end
Result => Unpermitted parameter: :full_name
3. Registration controller (option 3)
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: :create
protected
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: %i[full_name ])
end
end
Result => Unpermitted parameter: :full_name
In my gemfile:
gem 'devise', '~> 4.8'
In my routes:
devise_controllers = {
confirmations: 'users/confirmations',
registrations: 'users/registrations',
invitations: 'users/invitations',
}
devise_for :users, controllers: devise_controllers
I have read devise strong params but to be honest I do not know what I am doing wrong.
Also I tried to debug in Users::RegistrationsController#create what is happening with:
def create
super do
binding.pry
end
end
but it skips the debugger breakpoint... do you have any idea what is going on?
Cheers!
Edit:
Following suggestion from JohnP, I only left :full_name in devise keys parametter sanitizer for sign_up
Also I removed a callback that is bypassing my debug breakpoint and now I can stop with pry in create action
Generally, you write strong params for a specific controller, not in your ApplicationController, because the permitted conditions will be different for each model. When using devise_parameter_sanitizer, you only need to include the extra fields you're adding - this isn't setting up your strong params from scratch, just adding keys to the default Devise list.
So, you should find that this is all you need in your Users::RegistrationsController.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name])
end
(BTW, ensure you refer to the parameter correctly, as params[:user][:full_name].)
(Oh, and if you want to do debugging, I'd suggest installing the byebug gem. You just add an extra line byebug where you want to have a breakpoint.)
My goal is simple. I want to allow a user to sign up only if he possesses a unique secret code. I would like to check if this code is valid (being in my secret codes database) and then delete it once the user signed up.
I have a secret_code model with:
:secret_code column
I have a input for the secret code in my sign up form
<%= f.input :secret_code, required: true, autofocus: true %>
Should I personalize the class RegistrationsController < Devise::RegistrationsController?
How ? Thanks !
You can do that by overriding registrationcontroller. Uncomment create method like this.
def create
super
end
and add a filter like:
before_action :check_secret_code, only: [:create]
and you must modify your routes to tell devise use your controller instead of its default:
devise_for :users, controllers: { registrations: "users/registrations" }
you can specify what you want in that check_secret_code method and make render 'new' if code is wrong. Hope it helps.
You can achieve this with a simple before filter. This way you don't have to mess with devise code.
class RegistrationsController < Devise::RegistrationsController
before_filter :check_conditions, only: :create
def create
super
end
private
def check_conditions
#your conditions
end
end
Solved! Along to #Mehmet answer I had to cutomize application_helper.rb
module ApplicationHelper
def resource_name
:user
end
def resource
#user ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
end
And put include ApplicationHelper after the class name in registrations_controller.rb
So I have spent some time now trying to track down the illusive way to add a custom field to the field the "invitee" sends the invitation to.. My app is not a public facing app, and so the human resources department will send the invite upon hiring. However i would like to add basic information about the user being invited, and then they can fill out the non-pertinent info once they sign into the application..
is there a way to do this using a params sanitizer? i have only been able to find
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:fname, :lname, :mobiletel, :password, :password_confirmation, :invitation_token])
but I need to do this before the invite is sent out.
Any help would be greatly appreciated here!
This is how I approached it:
# config/routes.rb
# Use a custom invitations controller.
devise_for :users, controllers: { invitations: 'users/invitations' }
# app/controllers/users/invitations_controller.rb
class Users::InvitationsController < Devise::InvitationsController
before_action :configure_permitted_parameters
protected
# Permit the new params here.
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:invite, keys: [:email, :additional_fields, :added_here])
end
end
it worked for me, although instead of :invite I had to use :accept_invitation
I tried the following:
In user.rb:
before_create :record_sign_up_ip
protected
def record_sign_up_ip
self.sign_up_ip = current_sign_in_ip
end
Unfortunately, although current_sign_in_ip has my correct local ip of 127.0.0.1, sign_up_ip remains as nil. How can I easily get the IP of someone signing up? Normally I would put this in the create controller, but with Devise, there is no controller for User.
Override the controller used by Devise as noted at Override devise registrations controller
As modified from that post, create app/controllers/users/registrations_controller.rb:
# app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def create
params['user']['sign_up_ip'] = request.env['REMOTE_ADDR']
super
end
end
Also modified from that post, to use that controller:
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "users/registrations"}
You also need to make sign_up_up accessible (for Rails 3):
# app/models/user.rb
attr_accessible :sign_up_ip
In your user model,
def init
self.sign_up_ip = current_sign_in_ip
end
I'm going to create a multi user app, so, I will have a admin user that will have permission to create new ones.
I've created the UsersControllerbut when trying to create a new user, being already signed in, I'm getting redirect to root_path with an error message that says "You are already signed in".
So, what should I do to make this possible?
Found.
I have just to removed the registerable module from devise and it works.
In a controller method can't you just go:
def create_user
#user = User.new(:email => params[:email], :password => params[:password])
#user.save
...
end
This is how I am doing it in 2015
# in your terminal
rails g controller Registrations
Registrations controller should look like this,
# registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :require_no_authentication, only: [:new]
def new
super
end
end
The important line is the skip_before_filter...
That will disable the requirement that there be no user logged in.
The routes for the controller looks like this,
# routes.rb
devise_for :users,
controllers: {:registrations => "registrations"}
That will tell devise to use your custom registrations controller
Finally, setting up a custom route to that action:
# routes.rb
as :user do
get "/register", to: "registrations#new", as: "register"
end
There is another solution.
You must override registration controller and remove action (or actions) from prepend_before_filter.
DeviseRegistrationController source is here.
You can see:
prepend_before_filter :require_no_authentication, only: [:new, :create, :cancel]
It jumps into require_no_authentication before create method. If you want create new user while you are logged in, just remove :create from array.
I added in the Registrations Controller:
class RegistrationsController < Devise::RegistrationsController
...
skip_before_action :require_no_authentication, only: [:new, :create]
...
end
And it worked for me. I can now go and create a new user.
You could either override the default devise controller and add in your custom logic, or, It would probably be easier however to make a new (Admin) controller and simply create a user using one of it's actions.
#user = User.create!(:name => params[:foo], :email => params[:bar])
redirect_to #user
Devise has loads of guides on how to customise it's behaviour here: https://github.com/plataformatec/devise/wiki/_pages
This one in particular may be of interest to you: https://github.com/plataformatec/devise/wiki/How-To:-Manage-Users-with-an-Admin-Role-(CanCan-method) But make sure to have a look over the rest of the articles, there's a lot of them.
in case someone still looking for help, because it tooks a while for this to work , no clear answers
in your controller
class UsersController < ApplicationController
def new
#user = User.new
end
def add_user
#user = User.new(user_params)
if #user.save!
redirect_to root_path
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
in your routes :
get 'employees', to: 'users#new'
post 'employees', to: 'users#add_user'
and finally a form like this:
<%= form_for User.new , :url => {:action => "add_user"} do |user| %>
<%=user.email_field :email%>
<%=user.password_field :password%>
<%=user.password_field :password_confirmation%>
<%=user.submit 'add'%>
<%end%>
#Mourkeer +1
For simple_form 4.2.0 take #Mourkeer code and replace route.rb by:
# route.rb
devise_for :users, path_names: { registration: "registrations" }