Judging by the number of different StackOverflow questions, there are a lot of people trying to do this, and a lot of confusion. Here is how I did it, and hopefully it helps you.
I have a User and a Verifier model. What I want to do is create a new Verifier every time I create a new user, and pass in the user.id for the User into the verifier.user_id so that they are mapped together.
In order to do this I want to not really override but add additional functionality to the existing devise controller that handles when new users are created (and destroyed). So I need to access the RegistrationsController#Create function in devise.
First thing is to create a new folder in the ‘app/controllers‘ folder where we can put my custom controller. I called mine ‘app/controllers/my_devise‘. Then create a new file in this folder called registrations_controller.rb
It is called ‘registrations_controller‘ because that is what devise calls its controller that handles new user sign ups. We want it to inherit from the original devise controller:
Ok, so since I want to create some custom logic that happens when a new user is created, I want to override and customize the ‘create’ function:
So you’ll notice the ‘super’ command is called at the beginning. This is because I want to keep the original functionality of the devise create function, and just add my own additional logic. If you want to completely customize and override the devise create function, then you don’t want this line.
Now at fist I was tempted to use ‘if user.save’, because I want to create a new Verifier when a User is created, however the devise registrations controller uses ‘resource’, so thats what I want to access here. In my case, the model that I use with devise is User, so in my case ‘resource’ means ‘user’. Yours will depend on how you set up devise at the beginning.
Now importantly don’t forget to also delete the linked Verifier when the User is deleted. I used the same idea to override and customize the destroy function:
Some things to note here. I used the find_all_by_user_id function to get all the Verifiers that are linked to the User that we are destroying in this function. Since each User only has one Verifier, I could have used find_by_user_id. I decided to use find_all_by_user_id, just in case something weird happened and two Verifiers were linked to one User. This would ensure they all get deleted. Now note that find_all_by_user_id returns an array of values, even if the array only has a single element. So thats why I need to use the each function to iterate through the array, even if it only has a single element. This is because the destroy function cannot be called on an array, but only on a single instance.
So now when I create a new User, a Verifier is also created whose user_id value matches the User.id value.
Two things remain to do. First, we need to copy the ‘views/devise/registrations‘ files into a custom folder that matches the custom folder we made for our registrations_controller.rb. So I copied mine into ‘views/my_devise/registrations‘
Lastly we need to update the config/routes.rb file to point to our custom controller
If you get a routing error, try using { :registrations => "my_devise/registrations" }
I got an error in production when running on heroku, and using this route worked.
That’s it!
Now I’ve been thinking that there might be a better way to do this linking a Verifier with a User with rails associations, so if you know of one, please let me know!
Here is a link to the devise registrations_controller.rb so you can see the default functions. The devise documentation is also helpful, and I want to give credit to these StackOverflow questions which also helped me a lot. (one, two, three)
Want to learn more about Ruby on Rails? Checkout OneMonthRails, what I used to get started in Rails. Best Rails course I’ve ever seen!
0.000000
0.000000
Recent Comments