Model attribute is not being set when using devise? - ruby-on-rails

I used devise to create a user model. It contains all the default stuff from devise as well as 2 more database columns: first_name and last_name. Pretty simple stuff.
I am coding some tests to try it out:
#user = User.new(:first_name => "Ken", :email => 'myemail#gmail.com', :password => 'apassword')
#user.valid?
puts "user's first name: #{#user.first_name}"
puts #user.errors
In my model, I have this:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
validates_presence_of :first_name
end
For some reason, "first_name" is not getting set when I pass it in the constructor. The password and email are getting set, but not first_name.
Does anyone know why? I have played a bit with rails, and it works in other models. Why not with devise?

In your User model, write this:
attr_accessible :first_name, :last_name
and you are good to go.

Related

how to store ldap data in ruby on rails application database?

i have created a web app with rails4 and authentication system is developed with devise_ldap_authenticable gem.
where i am using username for login not email. but i want to store email in my users table.
My user model is
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
##attr_accessible :email, :password, :password_confirmation
# not required for LDAP :recoverable, :registerable, :validatable
devise :ldap_authenticatable, :rememberable, :trackable
validates_uniqueness_of :email, :allow_blank => true
before_save :get_ldap_email
def get_ldap_email
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username, "mail")
end
end
But in users table of email field its storing data like
`email` = '--- !ruby/array:Net::BER::BerIdentifiedArray\ninternal:\n- !ruby/string:Net::BER::BerIdentifiedString\n str: !binary |-\n cy5naG9zaEBzYW1zdW5nLmNvbQ==\n ber_identifier: 4\nivars:\n :#ber_identifier: 49\n'
My log says
LDAP: Requested param mail has value ["s.ghosh#example.com"]
How i will store this value to my users table. where im doing wrong? please help me out.
Just need to add the following then its totally ok
def get_ldap_email
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username, "mail").first
end

devise invitable do not validate model

First, excuse my poor english, I'm french... it's tricky to explain my problem !
I have a model User model in a Rails application:
class User < ActiveRecord::Base
attr_accessible :email, :gender, :lastname, :firstname
end
And a BackUser model that inherit from User:
class BackUser < User
# Class for Backoffice User
devise :database_authenticatable,
:rememberable,
:trackable,
:lockable,
:invitable,
:confirmable,
:validatable,
:validate_on_invite => true
attr_accessible :password, :password_confirmation, :remember_me, :active, :role
validates :role, presence: true,
inclusion: ["admin", "normal"]
validates :gender, presence: true
validates :firstname, presence: true
validates :lastname, presence: true
def admin?
self.role == 'admin'
end
end
This second class should validate the record before invite!
BUT, when I use the console to do the following:
u = BackUser.new
u.invite!
"u" is saved in database and an invitation is send to a blank email...
Do you know what I have to do?
Thans a lot!
I'm sure you've found a solution or workaround to your problem by now, but for any future SO users who encounter the same problem I found a pretty simple fix.
Devise Invitable's model configuration docs don't fully explain how to implement :validate_on_invite, but you have to set the configuration option to true - :validate_on_invite => true.
Here's what my devise method looks like in my User model for this to work correctly.
models/user.rb
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :validate_on_invite => true
Now when I attempt to submit an invitation it is fully validating the record with what the validations I've set up in my User model before allowing the invitation to be sent and the user record to be created. Looking at the docs, I'm guessing you can also enable this setting in the devise initializer, but I haven't tried going that route.
*Second possible option to enable validation if needed
config/initializers/devise.rb
config.validate_on_invite = true
I've never been able to get the validation to work correctly for devise invitable. You can't use RobHeaton's suggestion either because you will receive a validation error on the password. I use this little hack to get validation to work:
def create
#user = User.new(user_params)
#user.valid?
#user.errors.messages.except!(:password) #remove password from errors
if (#user.errors.any?)
render 'new'
else
#user.invite!(current_user)
redirect_to user_path(#user)
end
end
It doesn't solve the mystery of why your behaviour is occurring, but:
if u.save
u.invite!
end
will give the end result you are after.

How To Recover a Password with Devise ( Ruby on Rails)

I'm trying to recover a user's password with devise, but it generates the following error
undefined method `reset_password_sent_at=' for #<User:0x007fb78cfafb68>
Can anyone help me with this, since I'm new to Ruby on Rails?
What is the best way to recover a password and email the user using Devise? Thank you very much...
I'm use devise (2.2.3)
User.rb
require 'digest/md5'
class User < ActiveRecord::Base
# Setup accessible (or protected) attributes for your model
belongs_to :shop
before_create :compute_email_md5
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable,
:rememberable,
:trackable,
:validatable,
:token_authenticatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email,
:email_md5,
:password,
:password_confirmation,
:shop_id,
:role,
:terms,
:name,
:notify_on_order_received
validates :terms, :acceptance => true, :on => :create
end
THE SOLUTION IS
add reset_password_sent_at column to user table
As you've discovered, passord recovery requires that the model have a reset_password_sent_at column. Adding it via migration should solve this problem.
As for the reason this is happening, I'm guessing you added password recovery (the :recoverable module) after initially generating your Devise-enabled model (User). That's why Devise's generator didn't create that column for you.

alias_attribute and devise causing stack level too deep error

I am running into some slightly tricky issues with a legacy db. Everything seems to work fine if I simply change the "password" column name in the db to "encrypted_password"; however, I need to leave the db in place.
So I decided to use
alias_attribute :encrypted_password, :password
Now I get a "stack level too deep" error in the console.
My user model:
class User < ActiveRecord::Base
require "digest/sha1"
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :encryptable, :encryptor => :old_cakephp_auth
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :events
before_create :add_default_values
#alias_attribute :created_at, :created
#alias_attribute :updated_at, :updated
alias_attribute :encrypted_password, :password
def add_default_values
self.created = Time.now
self.updated = Time.now
self.image = ""
self.name = self.email.split("#").first
#make normal user
self.role_id = 2
self.username = self.email.split("#").first + rand(100000000000000).to_s
self.website = ""
end
def valid_password?(password)
return false if encrypted_password.blank?
Devise.secure_compare(Digest::SHA1.hexdigest(self.password_salt+password), self.encrypted_password)
end
end
Ideas? Thanks!!! :)
I imagine that this is due to devise reserving the word password for their own use (and it in turn calling encrypted_password. Try renaming it to pword and see if the error still occurs. If it doesn't, you'll have to find another name to call the aliased password.
I should say that this is just an assumption. Let me know if it helps.

Devise - login from two model

I have two user models, first is from remote database as legacy and for internal company purposes. (Employee logins). Second is our project for public registration and sign in but I want one login form. I have searching long time, but some solutions are confusing for me.
First legacy looks like (only for reading and authentication):
class CrmUser < ActiveRecord::Base
require Rails.root.join('lib', 'devise', 'encryptors', 'sha1')
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable, :rememberable, and :omniauthable
establish_connection "crm_data"
set_table_name :users
devise :database_authenticatable, :encryptable, :authentication_keys => [:login]
alias_attribute :encrypted_password, :crypted_password
alias_attribute :password_salt, :salt
# Setup accessible (or protected) attributes for your model
attr_accessible :login, :password, :password_confirmation, :remember_me, :role_id, :first_name, :last_name
And second, for public and registration:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable, :rememberable, and :omniauthable
devise :database_authenticatable, :registerable, :authentication_keys => [:login]
alias_attribute :login, :email
# Setup accessible (or protected) attributes for your model
attr_accessible :login, :password, :password_confirmation, :remember_me, :role_id, :first_name, :last_name
Now I don't know how to do that User controller try to authentication from first model, and when user doesn't exists, go to second model and try it again.
Using:
Rails 3.1
Devise 1.4.3
EDIT:
In wiki of Devise is something about multiple model, but I'm little bit confused, there are not example more complex.
Thank you.
Regards, Rado
You should monkeypatch find_for_authentication method from devise/models/authenticatable.rb
module Devise
module Models
module Authenticatable
def find_for_authentication(conditions)
#put your authentication logic here
end
end
end
end
About authentication logic:
Using two models for authentication in your case it's realy bad idea. How do u want build relations with two users models? It's a lot of unnecessary code.
Correct way of resolving your problem is make some synchronization between yours tables.
Try to authenticate user with base User model.
If user credentials was wrong - try to authenticate him with CrmUser model.
If authentication with CrmUser was OK add him to users table if he doesn't exists there already.
Return User's model object.

Resources