In devise's user table i'm trying to save email and password through a different controller , but in server log i'm getting this error ,
WARNING: Can't mass-assign protected attributes for User: encrypted_password
------------------------------------------------------------------------------
(0.1ms) BEGIN
User Exists (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'mail#mail.com' LIMIT 1
(0.2ms) ROLLBACK
Added encrypted_password attribute to the model.
So i'm not able to insert it to users table.
And ,How to encrypt password? as devise gem has built in.
Controller :
#user = User.new(:email => params[:supplier][:username],:username => params[:supplier][:username],:encrypted_password => '$2a$10$/Hh7UegsWm2ndRXbDEfjvOKBUiI1fa/z1GIbE5OYFpyqW6P97llsG')
#user.save
puts #user.errors
Model :
attr_accessible :encrypted_password
I would simply use
user = User.new(email: "...", password: "password", password_confirmation: "password")
user.skip_confirmation!
user.save!
This way, devise will do the work for you, and you don't have to bother about confirmation emails. If you want confirmation emails still to be send out, remove the second line
Related
I want to create a user manually through the console as such:
User.find_or_create_by(email: "user#mail.com", first_name: "Stan", last_name: "Smith", password: "password", password_confirmation: "password", confirmed_at: Time.now)
I have done this many times in past projects but this time it's not working. It is not picking up the Devise password model attribute so this is the error I get:
PG::UndefinedColumn: ERROR: column users.password does not exist
I have Rails 4.1.4 and Devise 3.3.0. Did something change in the latest versions?
Thanks.
Instead of User.find_or_create_by you should be using User.create.
Devise accepts a password and password confirmation on creation but the actual table only has a column called encrypted_password.
The "find" portion of User.find_or_create_by is looking for a column called "password" which doesn't exist.
Still if you want to use find_or_create_by, it accepts block:
User.find_or_create_by(email: "user#mail.com", first_name: "Stan", last_name: "Smith") do |user|
user.password = "password"
user.confirmed_at = Time.now
end
In my project I have implemented activeadmin gem, which is integrated with devise invitable. So in my application admin can invite a customer through an email. While inviting, i'm getting the following error:
*ActiveRecord::StatementInvalid in Admin::CustomersController#send_invitation
Mysql2::Error: Unknown column 'invitations_count' in 'field list': UPDATE `admin_users` SET `invitations_count` = COALESCE(`invitations_count`, 0) + 1 WHERE `admin_users`.`id` = 1*
This issue has happened after updating the gem devise_invitable to version 1.3.3
To fix it just create a migration
rails g migration AddInvitationsCountToAdminUsers invitations_count:integer
That should add invitations_count field to the table admin_users
For others who has got the same problem but in another table. Here is a migration for a general table users
rails g migration AddInvitationsCountToUsers invitations_count:integer
Such issue could be caught by rspec
it 'user can be invited with passing current_user' do
current_user_attr = {email: 'user1#example.com', password: 'xxxxxx', password_confirmation: 'xxxxxx', ... add your fields }
user_attr = {email: 'user2#example.com', password: 'xxxxxx', password_confirmation: 'xxxxxx', ... add your fields }
current_user = User.create!(current_user_attr)
user = User.create!(user_attr)
user.invite!(current_user).class.should eq(Mail::Message)
end
i need to select when devise send the confirmation mail. I overwrite the send_confirmation_instructions and add a date field named invited on my user model. If the invited field is null send the mail, otherwise not sent.
Here's my code:
def send_confirmation_instructions
unless invited.nil?
self.confirmation_token = nil if reconfirmation_required?
#reconfirmation_required = false
generate_confirmation_token! if self.confirmation_token.blank?
else
self.confirmation_token = nil if reconfirmation_required?
#reconfirmation_required = false
generate_confirmation_token! if self.confirmation_token.blank?
self.devise_mailer.confirmation_instructions(self).deliver
end
end
The output of my console its:
Loading development environment (Rails 3.0.10)
1.9.3-p0 :001 > User.create!(:email => "hello#test.com") NoMethodError: undefined method `reconfirmation_required?' for
I have rewrite many other devise method without problems. Any idea ?
Thanks in advance.
The best solution was to connect manually to the database and add the fields to the users table.
# read configuration from database.yml
config = Rails.application.config.database_configuration[Rails.env]
host = config["host"]
database = config["database"]
username = config["username"]
password = config["password"]
# stablish db connection
mysql = Mysql2::Client.new(:host => host, :username => username, :database => database, :password => password)
# generate devise confirmation token
token = (Digest::MD5.hexdigest "#{ActiveSupport::SecureRandom.hex(10)}-#{DateTime.now.to_s}")
# made the sql
sql = "INSERT INTO users (email, confirmation_token, confirmation_sent_at) VALUES ('email#test.com', '#{token}', '#{Time.now.to_s}')"
# execute query
mysql.query(sql)
# close mysql connection
mysql.close
I hope this will be useful.
If you haven't seen it yet, have a look at the latest railscast authentication in rails 3.1. He uses password_digest:string when generating the model and adds has_secret_password to the User model. He also adds some accessible_attributes, :password and :password_confirmation.
By using validates_confirmation_of :password we can make sure the password is confirmed before creating an instance. If I leave the password fields empty in my form I get this error message:
ruby-1.9.2-p180 :024 > u = User.new
=> #<User id: nil, name: nil, email: nil, password_digest: nil, created_at: nil, updated_at: nil>
ruby-1.9.2-p180 :027 > u.save
(0.4ms) SELECT 1 FROM "users" WHERE "users"."email" = '' LIMIT 1
=> false
ruby-1.9.2-p180 :028 > u.errors.full_messages
=> ["Password digest can't be blank"]
Of course we don't want to call the password field "Password digest" when communicating with our users. How do I change this error message?
Bonus question
When using validates_confirmation_of and using mismatching passwords I get two error messages telling me about it, and only the :password label and input tags are surrounded with fields_with_errors divs. If the passwords don't match I want to also highlight the password_confirmation input, if possible remove it altogether from the password part.
Should I write my own method for checking password confirmation? If so, could you provide some small guidelines?
The official way to solve this is to add the following to your locale file:
en:
activerecord:
attributes:
user:
password_digest: 'Password'
The English locale file is located at config/locales/en.yml. You may have to restart your server for the changes to be loaded in your environment.
To get rid of password_digest message, you can modify the view:
<% #user.errors.messages.delete(:password_digest) -%>
You could override the human_attribute_name method and set your own humanized version of the password_digest attribute. Try something like this:
HUMANIZED_ATTRIBUTES = {
:password_digest => "Password"
}
def self.human_attribute_name(attr, options={})
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
Then your error should look like this: "Password can't be blank"
I've been fighting with this for a couple of days and there doesn't seem to be much help online. I've looked at the Typus wiki, sample app, and tests and I appear to be doing things correctly but I stil get HTTP Status Code 302 (Redirect) where I expect 200 (Success) in my tests.
Below are what should be the appropriate files (with irrelevant stuff removed)
config/initializers/typus.rb (rails g typus:migration has been run as I have an admin_users table):
Typus.setup do |config|
# Application name.
config.admin_title = "Something"
# config.admin_sub_title = ""
# When mailer_sender is set, password recover is enabled. This email
# address will be used in Admin::Mailer.
config.mailer_sender = "noreply#somewhere.com"
# Define paperclip attachment styles.
# config.file_preview = :medium
# config.file_thumbnail = :thumb
# Authentication: +:none+, +:http_basic+
# Run `rails g typus:migration` if you need an advanced authentication system.
config.authentication = :session
# Define user_class_name.
config.user_class_name = "AdminUser"
# Define user_fk.
config.user_fk = "admin_user_id"
# Define master_role.
config.master_role = "admin"
end
config/typus/admin_user.yml
AdminUser:
fields:
default: first_name, last_name, role, email, locale
list: email, role, status
form: first_name, last_name, role, email, password, password_confirmation, locale
options:
selectors: role, locale
booleans:
status: Active, Inactive
filters: status, role
search: first_name, last_name, email
application: Admin
description: Users Administration
test/factories/admin_users.rb:
Factory.define :admin_user do |u|
u.first_name 'Admin'
u.last_name 'User'
u.email 'admin#somewhere.com'
u.role 'admin'
u.password 'password!'
u.token '1A2B3C4D5E6F'
u.status true
u.locale 'en'
end
test/functional/admin/credits_controller_test.rb:
require 'test_helper'
class Admin::CreditsControllerTest < ActionController::TestCase
setup do
#admin_user = Factory(:admin_user)
#request.session[:admin_user_id] = #admin_user.id
#request.env['HTTP_REFERER'] = '/admin/credits/new'
end
context "new" do
should "be successful" do
get :new
assert_response :success
end
end
end
#response.body:
<html>
<body>You are being redirected.
</body>
</html>
As you can see, I've set up the typus to use admin_user and admin_user_id for the session key. But for some reason that test fails getting 302 rather than 200. I'm sure this is because I'm doing something wrong that I just don't see. I've also created all these a gist, just in case someone prefers that.
Edited 2011-05-19 09:58am Central Time: Added Response body text per request.
I figured this out. It was a problem with the config/typus/admin_roles.yml file.
Before:
admin:
Category: create, read, update
Credit: read
...
After:
admin:
Category: create, read, update
Credit: read, create
...
The problem was that admin users didn't have access to the CREATE action on the admin/credits_controller which resulted in the user being sent back to the admin login address.
Giving admin users access to the action and changing the
#session[:admin_user_id]
to
#session[:typus_user_id] #Just like in the Typus docs
solved the problem. I had changed it to :admin_user_id because of the
config.user_fk = "admin_user_id"
in the typus config files, while trying to troubleshoot this issue.