I am creating a rails employee dashboard app where I am able to view a list of employees. For this application, I am the only user that should be able to view the administrative dashboard page. I've implemented my admin functionality by using the nifty administrate gem. An example app that showcases the dashboard can be found by viewing clicking this url Administrate example. My dashboard is identical and is nothing special. However, I will run into the occasion where I need to create other users/amins (Human Resources) to log in and to be able to edit, remove employee listings.
For authentication, I am using the awesome devise gem and am successfully able to login, signup, signout, etc. Here is the catch though. I need to be able to create new users through the administrate dashboard. I have the dashboard set up to display the user fields but I am currently unable to create a user. Here is a picture of my user dashboard for reference
The problem I am facing is that when I enter a password for Encrypted password I am unable to do so because of the Password can't be blank validation.
Viewing my logs, I am able to see that when I go to devise's signup page, it goes to a Devise::RegistrationsController while creation of my User with the administrate gem goes through Admin::UsersController. Surely, someone in the community has used a combination of creating users through an admin dashboard with devise. Does anyone have any recommendations of how to customize this functionality?
This seems like a problem with strong params. You have to sanitize those parameters. Cleanest solution, at least for me, is to override the RegistrationsController like so:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation) # list every parameter you'd like to register with
end
end
and map this controller in routes.rb like so:
devise_for :users, :controllers => { registrations: 'registrations' }
You can get inspired in this article.
Also I've noticed that you are trying to manipulate with encrypted_password field. That's not a good idea. Devise will handle that for you. You can render the input for password instead (that might as well be the issue all along).
The parameters seems to be the issue. You are trying to set protected parameters. Try sending only the following parameters.
[:name, :email, :password, :password_confirmation, :mobile ]
Make sure you have permitted above parameters in Admin::UsersController
After adding the user you have to confirm the user, if you have :confirmable in your user model. You can do so in Admin::UsersController after creation of user object.
user.confirm
Related
I have one user model and within that model I have roles (admin and general). I am using Devise https://github.com/plataformatec/devise and CanCan https://github.com/ryanb/cancan.
An admin creates the master account during their registration and then can register other users as well as edit their accounts. This works.
Finally, I have changed it so that the users can log in using their username and not email because email is not necessary for the general user.
My current (main) registration form (used only by the admin) requires the following information: First Name; Last Name: Email; Username and Password. I know that it is necessary for me to both validate certain fields and also make it so that usernames and email are unique. Both I know how to do.
USER MODEL
validates :username, :email, :password, presence: true
DB MIGRATE
add_index :users, :email, :unique => true
My problem is that when the admin creates the other users email is not applicable and also I want to include additional fields. Because email is not necessary and because I am using a single user model, validating that field or making it unique will not work. Or I do not think it will work?
If I do not want to separate out the model is their another direction I can approach this to solve the problem. I am thinking two registration forms -- but still the issue of validation and uniqueness will be present.
Any guidance would be appreciated.
Have you considered a method in your application controller to create users like so:
def create_new_user
u = User.create(:email => "guest_#{Time.now.to_i}#{rand(99)}#example.com", :password => params([:password]), :username => params([:username]))
u.save!
end
You could create a form that admin could use to get username and any other parameters you need to this method.
Alternatively, you can generate the devise views and customize them to suit your needs.
rails generate devise:views
Then you can move :email into a hidden field (it will still be present and so pass validation) in the form and set it randomly like above. This will handle the unique issue. You can also add other attributes like you wanted.
Keep in mind though that if you want to create a Devise resource while signed in as a devise resource, you'll have to customize a few things in the registrations controller.
Devise has some good info on custom views. https://github.com/plataformatec/devise
I'm having an issue using Devise. Well this is not really an issue but more a "I don't know how to do".
I'm actually using Devise 3.1.0 on my Rails 4 application. So far I only had my sign up through which users could go and register themselves into the system.
The problem is that now, I'm adding groups and roles to every user since each user gonna belong to a specific group (a company per se). So in that case, when a user first register, he register as admin and create his company. But let's say that from the inside of this application, this admin wants to create other users which all belongs to that sepcific company.
I know I could override the Devise::RegistrationController but looking at their original update method makes me feel that the code gonna be bloated if I copy their code and hack around mine in order to make it works.
My concern is especially about the strong parameters. Let me explain, actually I override the account_update_params on Devise::RegistrationsController as it :
protected
def account_update_params
params.require(:user).permit(:lastname, :firstname, :email, :current_password, :password, :password_confirmation)
end
But if I want to add account from the application as admin, I need to also allow :role which can be a security issue in the register form. What if someone try to inject something into role while register?
How to do it the best way to allow :role only inside the application but not when logout?
Thanks to everyone
Yes I too hate overwriting devise controllers. Part of the problem with devise is that it can be somewhat rigid and uncustomizable.
In your routes.rb file, create a new route.
get '/users/sign_up_as/:role' => 'devise/registrations/#new', :as => 'new_user_registration'
and then modify the devise registration view with the line
<%= f.hidden_field :role, :value => params[:role] %>
To make a link for sign up you could do
= link_to 'Sign Up', new_user_registration_path(:role => 'admin')
Also keep in mind that you are not required to use the devise registration controller for the form itself. If you run User.create, devise will still send the confirmation email, etc.
Here is how I do it
Assumptions:
1. When a user signs up, he is the admin for the new company
2. Users can be created in app by admins or some other logic that you will apply
First, create an after_create for the User model in app/models/user.rb
class User < ActiveRecord::Base
after_create :set_account_and_admin
protected
def set_account_and_admin
if self.account_id.nil?
#account = Account.create!
self.update(account_id: #account.id, admin: true)
end
end
Then override devise create in app/controllers/registrations_conroller.rb
def create
build_resource(sign_up_params)
if current_user
resource.account_id = current_user.account_id
end
#...rest of devise stuff taken from the gem
end
Now when someone goes to your sign up app and puts in user/password they will get a new account and the User model will create a new account for you and setup that new user as an admin.
If that user logs in they can create new users then devise will see that the user is logged in and assign the new users to the current users account.
Now you can add whatever logic for admin/groups and who can create new users and not have to worry about adding the logic to the form.
Another alternative to this is to make a separate action in the controller like 'inappcreate' and route to that in the user _form.
I'm using rails 3.2 and devise 2.1 to create a multi-site CMS
Requirements
Sites based Basecamp subdomains.
Have 3 "user" models. 1. Admin(superuser) 2. Authors(each have their own site on subdomain) & Subscribers(read the sites ).
Authors: registration is normal username/password combo but needs to be approved by admin. their registration form will have subdomain field.
Subscribers: registration happens by invitation email.
need separate login & registration forms
Possible Solutions
I have been searching & found few solutions
3 Separate models in devise:
$ rails generate devise admin
$ rails generate devise author
$ rails generate devise subscriber
but this gives the following error
$ rails generate devise author
/home/gaurish/.rvm/gems/ruby-1.9.3-p286-perf/gems/devise-2.1.2/lib/devise/rails/routes.rb:443:in 'raise_no_devise_method_error!': Admin does not respond to 'devise' method. This usually means you haven't loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' inside 'config/initializers/devise.rb' or before your application definition in 'config/application.rb' (RuntimeError)
STI: single table in the database and for each user type create a model
class Admin < User; end
class Author < User; end
class Subscriber < User; end
Here, I am not sure how this would handle different login/registration workflows. example for subscriber I am planning on using devise_invitable for creating invitations. Admin doesn't need to scoped on basis of subdomains unlike authors & subscribers.
Does this seem complicated? I hope I was able to explain well.
You don't need to have three separate models to build this functionality. What you want to look at is the concept of Roles which are applied to one User model.
There is a Gem which provides this capability called Rolify and can be found at https://github.com/EppO/rolify
This would allow you to specify which users are in which Roles and change them as you see fit, all from one existing model.
Once you have Roles attached to the User model, you can override Devise's registration controllers to detect the Role and render different templates etc. You would do this by:
Running rails generate devise:views to unpack the views from the Devise gem into your project
Create your own Registrations controller:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
super
# Add logic here to detect Role and display different forms
end
def create
super
end
def update
super
end
end
Add the correct settings in your routes.rb file to tell Devise to use your new controller:
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
Admin does not respond to 'devise' method.
This may be cos you're also using the activeadmin gem, or something that uses a module called Admin, which causes a name conflict. Try renaming the model to AdminUser
I'm using devise and cancan as an authentication solution.
For devise I have added a role attribute, and created a constant ROLES:
#Migration for adding roles
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :string
end
end
#Users.rb
ROLES = %w[user staff]
I want to add a function to the signup page, such that for a person to create a user with the role "staff" he has to enter a secret key as well (probably like a secret code like "staffsecretkey" in a input text box)
Anyone know of a way?
Thanks in advance.
You'll have to do two things:
1) Override devise controllers
2) Customise your views
Check devise wiki in github. You should be able to find all the info you need right there. I'm answering you from my BlackBerry so I could no give you more details right now. But if you can't solve this with the answer I gave you. I'll give you a hand later.
I've started to implement a new project using Devise, which is pretty fantastic for handling users. However, when a user signs up, they're not just creating a User model, but also need to create a related Account model that represents the company. Additional users will also belongs_to this Account model.
I can't seem to find a hook for this in Devise, though it seems like a pretty common pattern. What's the best practice for this?
I should also mention that there are a couple of fields for the Account that need to be provided on the sign_up form, so just something like this in the User model:
after_create :make_sure_account_exists
def make_sure_account_exists
if self.account.nil?
#account = self.create_account({ :company_name => '???' })
end
.. as I'm not sure how to get the company name.