After setup devise and simple_token_authentication and configure the
ApplicationController
acts_as_token_authentication_handler_for User
respond_to :html, :json
protect_from_forgery with: :null_session
before_action :configure_permitted_parameters, if: :devise_controller?
protected
#added username to signup
def configure_permitted_parameters
added_attrs = [:name, :username, :email, :password, :remember_me, :avatar, :avatar_cache, :remove_avatar]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
end
#Override authenticate_user! to handle html and json separately
def authenticate_user!
if self.request.format.html?
super
elsif self.request.format.json?
if self.request.parameters["controller"].start_with?("devise")
# use the default if session related
super
else
# others
if user_signed_in?
# use the default if already signed in
super
else
redirect_to root_path
end
end
end
end
When click on the User Edit Profile shows:
ArgumentError in Devise::RegistrationsController#edit wrong number of
arguments (given 1, expected 0) Extracted source (around line #20):
the error points to authenticate_user!
def authenticate_user!
if self.request.format.html?
super
elsif self.request.format.json?
in this case cant Override the authenticate_user!?
Or this is related with rails 5.1?
Someone is having this issue with simple_token_authentication?
The error message is telling you that Devise defines a method named authenticate_user!, which takes one argument. You are overriding the method, but your method doesn't take any arguments. At some point, Devise makes the call authenticate_user!(some_arg_here), so you get the error explanation:
Called with one arg...
|
V
wrong number of arguments (given 1, expected 0)
^
|
...but the method def expects 0 args
Here's a simple example of your error:
class Dog
def bark
puts "wuff"
end
end
Dog.new.bark(3)
--output:--
1.rb:2:in `bark': wrong number of arguments
(given 1, expected 0) (ArgumentError)
Here's the fix:
class Dog
def bark(repeat)
puts (["wuff"]*repeat).join(", ")
end
end
Dog.new.bark(3)
--output:--
wuff, wuff, wuff
So you need to define your authenticate_user! method so that it takes one argument. If you don't care about the argument, then name it trash.
Related
I am attempting to configure a different Devise strong parameter sanitizer per model following the instructions at; https://github.com/plataformatec/devise#strong-parameters
I have created a new file named parameter_sanitizer within my Employer model directory;
app/controllers/Employers/paramater_sanitizer.rb
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
devise_parameter_sanitizer.permit(:sign_up, keys: [:forename, :surname, :username)
end
end
Within my application controller I have;
require 'employers/parameter_sanitizer'
class ApplicationController < ActionController::Base
before_filter :devise_parameter_sanitizer, if: :devise_controller?
protect_from_forgery with: :exception
protected
def devise_parameter_sanitizer
if resource_class == Employer
Employer::ParameterSanitizer.new(Employer, :employer, params)
else
super # Use the default one
end
end
end
The error I get from signing up an Employer object is;
NameError in Devise::ConfirmationsController#show
undefined local variable or method `devise_parameter_sanitizer' for #
Any advice on how to overcome this?
Thanks,
Mark
In this initialize method you save the params as an instance variables #params so in your method you should do:
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
#params.permit(:sign_up, keys: [:forename, :surname, :username])
end
also I believe this should work without specifying #params
Explanation
to find the solution to this problem check the devise api to better understand the methods you are calling and read the `Devise::ParameterSanitizer source code
I am quoting their ruby-rocs about the #permit() method
Instance Method Details
#permit(action, keys: nil, except: nil, &block) ⇒ Object
Add or remove new parameters to the permitted list of an action.
Arguments
action - A Symbol with the action that the controller is performing, like sign_up, sign_in, etc.
keys: - An Array of keys that also should be permitted.
except: - An Array of keys that shouldn't be permitted.
block - A block that should be used to permit the action parameters instead of the Array based approach. The block will be called with an ActionController::Parameters instance.
Examples
# Adding new parameters to be permitted in the `sign_up` action.
devise_parameter_sanitizer.permit(:sign_up, keys: [:subscribe_newsletter])
# Removing the `password` parameter from the `account_update` action.
devise_parameter_sanitizer.permit(:account_update, except: [:password])
# Using the block form to completely override how we permit the
# parameters for the `sign_up` action.
devise_parameter_sanitizer.permit(:sign_up) do |user|
user.permit(:email, :password, :password_confirmation)
end
Returns nothing.
Also I quote
If you have multiple Devise models, you may want to set up a different parameter sanitizer per model. In this case, we recommend inheriting from Devise::ParameterSanitizer and adding your own logic:
class ApplicationController < ActionController::Base
protected
def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super # Use the default one
end
end
end
User::ParameterSanitizer.new(User, :user, params) will call this initializer method from parameter_sanitizer.rb source code
def initialize(resource_class, resource_name, params)
#auth_keys = extract_auth_keys(resource_class)
#params = params
#resource_name = resource_name
#permitted = {}
DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
permit(action, keys: keys)
end
end
so basically you are calling initialize(User, :user, params), I don't understand why devise is accepting params in this method, as it has his own way of allowing attributes by saving a static hash of permitted field.
DEFAULT_PERMITTED_ATTRIBUTES = {
sign_in: [:password, :remember_me],
sign_up: [:password, :password_confirmation],
account_update: [:password, :password_confirmation, :current_password]
}
and the permitting them with a loop
DEFAULT_PERMITTED_ATTRIBUTES.each_pair do |action, keys|
permit(action, keys: keys)
end
In this initialize method you save the params as an instance variables #params so in your method you should do:
class Employer::ParameterSanitizer < Devise::ParameterSanitizer
def initialize(*)
super
#params.permit(:sign_up, keys: [:forename, :surname, :username])
end
I've some additional fields to the "accept inviation form" and I need to permit them in a controller. I did this according to the documentation:
class Users::InvitationsController < Devise::InvitationsController
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def accept_resource
resource_class.accept_invitation!(update_resource_params)
end
def configure_permitted_parameters
# error here
devise_parameter_sanitizer.for(:accept_invitation).concat [:field1, :field2, :field3]
devise_parameter_sanitizer.for(:accept_invitation) do |u|
u.permit(:field1, :field2, :field3, :password, :password_confirmation, :invitation_token)
end
end
I need to allow ":field1, :field2, :field3". Am I doing it right? I have an error
undefined method `for' for #<Devise::ParameterSanitizer:0x007f20fe0d5220> Did you mean? fork
Method for was deprecated and successfully removed from Devise.
Use permit/sanitize instead, or downgrade to 4.0 (not recommended).
Is ApplicationController inherits from DeviseController?
Otherwise how devise methods are available in ApplicationController.
ApplicationController inherits from ActionController::Base, which
defines a number of helpful methods.
ref
Devise::Controller has a several modules that's hooked up in to ActionController on_load.
For example the Devise::Controller::Helpers module defines and loads helpers below:
# Generated methods:
# authenticate_user! # Signs user in or redirect
# authenticate_admin! # Signs admin in or redirect
# user_signed_in? # Checks whether there is a user signed in or not
# admin_signed_in? # Checks whether there is an admin signed in or not
# current_user # Current signed in user
# current_admin # Current signed in admin
# user_session # Session data available only to the user scope
# admin_session # Session data available only to the admin scope
#
# Use:
# before_action :authenticate_user! # Tell devise to use :user map
# before_action :authenticate_admin! # Tell devise to use :admin map
ApplicationController doesn't inherit from DeviceController. ApplicationController inherits from ActionController::Base. In ApplicationController the method you talking about configure_permitted_parameters is used with before_filter which is callback.
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }
end
No , Application Controller doesn't inherits from Devise controller.It is the base.To use devise methods in it, you can use the below:
before_filter :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.for(:account_update) << [:first_name, :last_name, :is_active]
devise_parameter_sanitizer.for(:sign_in) << [:user_name]
devise_parameter_sanitizer.for(:sign_up) << [:first_name, :last_name,:username,:is_active]
end
def after_sign_in_path_for(resource)
"some path"
end
No, ApplicationController is the base, like the name, is the controller for the all application.
ApplicationController is extended from DeviseController.
i am new to rails and any advise and help will be much appreciated.
I am currently using devise confirmable
When a user signs up for the first time they get:
Re-directed to the application root at localhost:3000
Flash notice saying "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
So far so good.
I am trying to redirect the user to a different page when they signup
but unsure how - any advise would be much appreciated
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def after_sign_in_path_for(resources)
if userr_signed_in?
dashboard_path
elsif usera_signed_in?
admin_path
else
dashboardj_path
end
end
def after_sign_out_path_for(resources)
new_feedback_path
end
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:email) }
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:category_businesstype_id, :firstname, :lastname, :companyname, :email, :password, :category_role_id, :staff, :number, :hear, :city, :category_qualification_id, :language, :category_careerlevel_id, :desiredjob, :category_distance_id, :category_cvpreference_id, :category_joboption_id, :preferedlocation, :category_notice_id, :category_country_id, :category_positiontype_id ) }
end
end
According to your case, you want to redirect user after signup on a specific path. For that you need to override after_sign_up_path instead of after_sign_in_path.
In application controller you should have this method
def after_sign_up_path_for(resource)
after_registration_path // Your path should goes here
end
After sign_in path can only be used when you are trying to actually log in user to your system immediately after registration. Here you have to just redirect a user.
I've been busting myself for a ton of hours now on how to do this.
I have 2 models.
intern.rb
company.rb
I've been able to add custom fields on registration, for me that was :name. I did that by adding:
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |i| i.permit(:email, :password, :name) }
end
I've been reading up on the devise readme and trying to understand how to add it so it's specific to one user model. But I get an error every single time.
I tried creating a controller called:
interns_controller.rb
with the code:
class Intern::ParameterSanitizer < Devise::ParameterSanitizer
def sign_up
default_params.permit(:email, :password, :name)
end
end
and then adding this into the
application_controller.rb
code:
protected
def devise_parameter_sanitizer
if resource_class == Intern
Intern::ParameterSanitizer.new(Intern, :intern, params)
else
super
end
end
however I get an error. What am I doing wrong here?
Image with error: http://s12.postimg.org/fqpwyzzdp/Screen_Shot_2014_06_17_at_15_41_58.png