Devise set_flash_message! not working in custom devise controller - ruby-on-rails

Because of an api I'm using, I need to take out Devise's registrationsController create action. I have gotten this to work in every way except one. For some reason, the set_flash_message method returns the error:
NoMethodError - undefined method `set_flash_message!' for #<Users::RegistrationsController:0x007f91f8e8b070>:
app/controllers/users/registrations_controller.rb:28:in `create'
Here is the controller code:
class Users::RegistrationsController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
resource.save!
yield resource if block_given?
if resource.persisted?
puts "resource persisted".green
if resource.active_for_authentication?
flash[:success] = "Welcome! You have signed up successfully."
# set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
puts "not sure about this".blue
set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
# flash[:danger] = "signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
puts "resource did not persist".red
clean_up_passwords resource
set_minimum_password_length
# respond_with resource
puts "NOW WE KNOW".on_red
render 'new' #not sure if this works
end
end
end
I've put in flash messages the normal way for now but it's already causing some problems. How do I get set_flash_message to work?

I ran into the same issue. Turns out this functionality was recently changed in Devise (January 28, 2016).
So you either need to update the version of Devise that you use in your app or use the old way of calling set_flash_message, which was:
set_flash_message :notice, :signed_up if is_flashing_format?

Related

How to edit create registrations_controller action using devise?

I'm making a simple app that has the traditional User model, but also a Patients model. I want a user to automatically become a patient on sign up.
I've managed to follow instructions here, and can see the file users/registations_controller.rb, but I'm not sure what to add to it.
I have pasted the existing devise create code from here
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
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}"
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
end
and I want to add functionality to do this too:
# #user = User.new(user_params)
#patient = #user.build_patient
#patient.save
But I don't know how to do that? (do I just add the code and replace 'user' with 'resource'?)
You can do it by adding block code like this instead of copy the Devise code
class YourController < Devise::RegistrationsController
def create
super do |user|
#patient = user.build_patient
#patient.save
end
end
end

change registrationcontroller create action failure redirect path

I'm trying to implement a signup form on the homepage of my app. The successful flow (registering) works perfectly. The problem lies in when a validation fails, namely triggering a rerender of the devise registration :new action. I would like this rerender to happen on the homepage instead of devises own view.
I've tried to rewrite the devise controller by adding the root_path location to the "respond_with location" as seen below, however for some reason this continues to trigger a render of the devise views.
# POST /resource
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
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}"
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, location: root_path # HERE!!!
end
end
I'm wondering what a clean way would be to fix this problem
EDIT
It just struck me that I could render the home layout with the preferred template, however this feels a bit improper.
# POST /resource
def create
build_resource(sign_up_params)
resource.save
yield resource if block_given?
if resource.persisted?
if resource.active_for_authentication?
set_flash_message! :notice, :signed_up
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}"
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
render layout: 'frontend/home', template: 'frontend/home/index'
end
end
I eventually went with the approach as appended with the edit above:
render layout: 'frontend/home', template: 'frontend/home/index'

Rails double render error despite using if then statement

I frequently use both render and redirect_to but combining in an if...then statement so that the action by default only has 1. Not sure why this is not working in this case with Devise.
What I need to do is whether a user is confirmed or not, immediately after s/he signs up successfully I need to POST to another controller to create some other things, which is why the redirect_to is the same. But I'm getting the DoubleRender error
Thanks!
For your reference, this is the Devise code:
# POST /resource
def create
build_resource(sign_up_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
end
Then my code:
def after_sign_up_path_for(resource)
redirect_to "/plan_date_create"
end
def after_inactive_sign_up_path_for(resource)
redirect_to "/plan_date_create"
end
The respond_withs do a render and then after_sign_up_path_for and after_inactive_sign_up_path_for do redirects, and you're calling both respond_with and one or the other of those methods on the same line of code.

Overwriting 'Devise::RegistrationsController' with custom create gives NoMethodError

Please let me know if I'm going about this the wrong way. I'm trying to add a couple custom attributes to a User in the create method as well as call my Analytics method if the user is saved.
I defined a new controller:
class RegistrationsController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
resource.public_id = Utilities::generate_code
resource.referral_code = Utilities::generate_code
if resource.save
Analytics.identify(
user_id: resource.id.to_s,
traits: { email: resource.email })
yield resource if block_given?
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
respond_with resource
end
end
end
The only thing different in this create method is that I'm adding referral_code and public_id before the save and running Analytics after.
Analytics.identify(
user_id: resource.id.to_s,
traits: { email: resource.email })
When I create a user I'm getting
undefined method `is_flashing_format?' for #<RegistrationsController:0x007fdba130d9a8>
I don't understand why this method isn't being inherited. Is this even the proper way to modify devise or to add attributes/add analytics?
I figured it out, I'm using Devise version 3.1.1 (locked for dependencies), it looks like is_flashing_format? was added last month in 3.2.0.
I changed the method in my controller to is_navigational_format? and all is well!

What does the devise default create action look like?

So, I'd like to add this bit of code to the devise registrations controller.
When I'm calling #user.save. just before that, I need to call, #user.uid = SecureRandom.hex(whatever-value).
However, I don't want to change the way the create action currently functions. I'd just like to add the #user.id = SecureRandom.hex line.
So, how does the original devise create action look?
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
def create
build_resource(sign_up_params)
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_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_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
even more docs:
https://github.com/plataformatec/devise/wiki

Resources