Extending Devise Registration Controller - ruby-on-rails

I have an Accounts model set up with Devise. Devise uses a few attributes (such as email, password etc.) but I have a few other attributes that I made. On sign up, I'd like to set them up in a way.
How can I extend the registration controller? I understand that I need to actually create a new controller like this:
class AccountsController < Devise::RegistrationController
def create
super
end
end
Can I just add my code right after super? I think it would be too late as the resource would have already been saved. What's the best way to do this?
If I were to write create from scratch, how would I know that I didn't miss anything that Devise does?
Thanks,

According to the Devise documentation, yes, just like Josh's answer, you would change the controller. Although, you don't have to start completely from scratch. Take a look at the documentation.
You can generate the controller so you are able to add customizations:
Example: rails generate devise:controllers [scope]
So, you could run the following for your Users scope:
rails generate devise:controllers users
This gives you the controllers in a folder located here:
app/controllers/users
Then, tell your routes file to use that controller. Update your devise route to look like this:
devise_for :users, controllers: { sessions: "users/sessions" }
And finally, copy over all the views. If you haven't genereated the views yet, you'll need to do so. The controller has changed, so your views will need to as well.

If you want to rewrite the controller from scratch for full control, start with the registration_controller.rb Source Code and make your changes as necessary.
Telling devise to use your custom controller is as simple as changing the route:
devise_for :users, :controllers => { :registrations => "users/custom_controller" }

If you want to fields for user supplied information there's no need to extend controller.
If you want to add those automatically, there's no reason not to do it in model! (unless it depends on session or request)
In 1st case, see https://github.com/plataformatec/devise#configuring-views
You should change DEvise controller ONLY if you intend to change signup flow.

Related

Is there a way to pass data like ID or an array from a controller to a devise view? [duplicate]

I want to customize devise session & registration controller.
I am even adding Active Admin to the app.
What is the correct process to override these controllers?
& I want to use both the controllers(customized as well as original). Is it possible?
Active Admin - original devise controllers
normal user - customized controllers.
When we are creating customized controllers, does same name cause any problem?
Thanks,
Avi
If you want to add a admin role to your devise, have a look at https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role.
If you want to customise your current devise You can customise the devise views by copying the views from the gem into your application and then modifying them. The below line would copy the views into your application
rails generate devise:views
If you want to modify controllers, Follow below steps
You would have to create your own customise controller say Admins::SessionsController
class Admins::SessionsController < Devise::SessionsController
end
Note that in the above example, the controller needs to be created in the app/controller/admins/ directory.
Now tell the router to use this controller
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
And since we changed the controller, it won't use the "devise/sessions" views, so remember to copy "devise/sessions" to "admins/sessions".
There is a rail cast video for active admin at http://railscasts.com/episodes/284-active-admin

How can I create custom login page URLs in Rails/Devise for partner links?

I have a Rails 4 application using Devise for authentication.
In addition to the standard Devise login page, I want to have partner login pages that basically look and function the same way, but have a unique URL, like:
http://example.com/partner1
What is the best way to do this? I'm not sure how the routes file should look. And is using FriendlyID a good idea as well?
I have a PartnerPage model in the database which contains a "link" field, which is where the admin will enter the link/partner code.
Creating a custom route to the signup form is pretty straight forward:
get '/partner1', to: 'devise/sessions#new'
However if you want to have a customized login screen a good solution is to subclass Devise::SessionsController.
# app/controllers/partner1/sessions_controller.rb
class Partner1::SessionsController < Devise::SessionsController; end
and in your routes:
get '/partner1', to: 'partner1/sessions#new'
This will render app/veiws/partner1/sessions/new.html.erb.

How to add a view in rails

I am quite new to rails but i have searched a lot how to do this but it doesnt seem to work for me. Im trying to create a new view called request for my model called steppy_steps, so i created a new file in the views directory called request.html.rb, added this to my routes, match '/request' => 'pages#request', also tried get "steppy_tests/home", and lastly added (def request, end), to my Steppy_Tests_Controller.rb but when i check the url it gives me an error:Couldn't find SteppyTest with id=home
I cant figure out what to do any help would be great! Thanks in advance.
You should read up on the MVC programming pattern (which is what Rails is based on)
In order to make a view, you need to have the controller and model aspects in place too. I think you're doing this already, but to help you understand more, I'll outline below:
Views : Controller Actions
If you want to show a view from the steppy_steps controller, you need to first have a controller action set up to handle the request. You'd normally use a self-named controller for this (controller name steppy_steps), and have various actions for that
In your routes, you'll then "capture" the request to your steppy_steps controller like this:
#config/routes.rb
resources :steppy_steps
This will create a set of RESTful routes, which you can then translate into your controller, like this:
#app/controllers/steppy_steps_controller.rb
def index
#Index code
end
def show
#Show code
end
This will allow you to create a views directory which can contain the views for /views/steppy_steps/show.html.erb and /views/steppy_steps/index.html.erb
Routes Are Super Important
The error you're getting is caused by you sending /home to your view
The problem here is that if you're using a route which has an in-built id param (the show action routes have this), then Rails will look for the extra params after the URL
To fix this, you'll have to provide more of your code, but I also believe you'd be better understanding the fundamentals of Rails a little more
Adding Routes
You can add routes & views as you wish
If you're looking to add a requests route / view, I'd do this:
#config/routes.rb
resources :steppy_steps do
collection do
get :requests
end
end
This will allow you to create /steppy_steps/requests

How to add new controllers to devise controllers structure?

i have a functional application that have a devise merchant model and i've overwritted the registration controller, so i have a folders structure like
app/controllers/merchants/registrations_controller.rb
now i'm trying to add a new controller called products in order to have something like
app/controllers/merchants/registrations_controller.rb
app/controllers/merchants/products_controller.rb
When i perform
rails g controller
i get all the files required, but for some reason next to it i can't perform rake's or generators 'cause of this error
undefined method `devise' for #<Class:0x007f929f5b5408>
this ever happen when i add a new controller to a devise folder, in this case the merchants folder... is there a reason why i can not or i should not do this?
how can i accomplish this?
maybe there is a better approach to do this... if is that the case, could be great know it ;)
update: the goal is group all the controllers related to the merchants under merchants folder, also i figured out that the issue is generated by a helper file generated in app/helpers/merchants/products_helper.rb so deleting this file the exception dissapears... but why?
Why did you add the products_controller to your devise merchants folder? If the goal is to authenticate merchants for the products controller, here is the way to do it:
Put your product_controller.rb in app/controller/ as usual and had this filter in it:
before_filter authenticate_merchant!
Check that you have this in your route.rb (for the custom registrations controller):
devise_for :merchants, :controllers => {:registrations => "merchants/registrations"}

devise - Customizing the User Edit Pages

currently with devise & rails 3 there is a one page user edit page: /users/edit
I would like to split that out into sections for a better UI, something like:
/account/settings
/account/password
/account/notices
/account/disable
Also, I'd like to require the user to enter their current password when a user wants to change their password.
With devise, to make this happen, does this require a new controller, or can this all be handled with routes?
Also, currently, the edit page lives here: app/views/devise/registrations
Do you recommend adding these pages there? Or in /app/views/users ?
Thanks
You have multiple options here. I would go with the first option as it seems to more naturally fit what you are trying to do.
Override devise's registrations controller by inheriting from it, and update the corresponding views and routes. Here is what devise's site says about this:
Configuring controllers
If the customization at the views
level is not enough, you can customize
each controller by following these
steps:
1) Create your custom controller, for
example a Admins::SessionsController:
class Admins::SessionsController < Devise::SessionsController
end
2) Tell the router to use this
controller:
devise_for :admins, :controllers => { :sessions => "admins/sessions" }
3) And since we changed the
controller, it won’t use the
"devise/sessions" views, so remember
to copy "devise/sessions" to
"admin/sessions".
Remember that Devise uses flash
messages to let users know if sign in
was successful or failed. Devise
expects your application to call
"flash[:notice]" and "flash[:alert]"
as appropriate.
Use the User controller and add actions there with corresponding views (not my choice)

Resources