I am trying to implement a user authentication system inside rails, this is my model:
class User < ActiveRecord::Base
attr_accessible :id, :email, :name, :password, :created_at, :updated_at
has_secure_password
before_save { email.downcase! }
validates :email, presence: true, :uniqueness => { :case_senstive => false }
validates :name, presence: true
validates :password, presence: true, length: { minimum: 6 }
end
Running in the console i can read the User table successfully, then when i try to create a record:
User.new(:name => "A", :email => "a#a.a", :password => "password")
running valid on it retrurns true, but when saving the record, i get error:
users.password may not be NULL
Extracting the password out of the hash works fine.
What is the problem?
Thanks
Where are you setting :password_confirmation? The example in the docs suggests you need it.
http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html
Main problem is in has_secure_password. If you are using that you should have string field :password_digest (it's where your encrypted password will be saved). And you need delete field :password and your validator of presence for that too. After add gem 'bcrypt-ruby', '~> 3.0.0' .
And now that should work
user = User.new(:name => "A", :email => "a#a.a",
:password => "password", :password_confirmation => "password")
But better use great gem https://github.com/plataformatec/devise . It has everything you need.
NEW ADDED
you should have attr_accessible for :password_confirmation too and that field should be used in your form.
more info about has_secure_password
Related
I've added two news fields to my users table :first_name and :last_name
In migration file I've specified these fields couldn't be null using the following code:
class Userscustomfields < ActiveRecord::Migration
def change
add_column :users, :first_name, :string, {:null => false, :limit => "128"}
add_column :users, :last_name, :string, {:null => false, :limit => "128"}
end
end
I've checked on my database and the table was configurated correctly. But when I'm going to do a new register, my rails app allows to me to add a new user with first and last names empty. The app saves the fields with "", which didn't worked as I expected.
How can I do prevent this, by making a check of emptiness on my field before save them on my database?
I put on model user.rb
validates :first_name, :last_name, presence: true
I'm running rails 3.2.5 with the latest Devise gem. And i have a user class that is related to an Actor class. There is a field called slug that validates fine if I use the following syntax...
validates :slug, :presence => true, :length => { :maximum => 50 }
But if I place the extra uniqueness argument
validates :slug, :presence => true, :length => { :maximum => 50 }, :uniqueness => true
it throws an error...
NoMethodError in Devise::RegistrationsController#update
undefined method `text?' for nil:NilClass
I'm not sure what is causing such.
I should also mention that in my user model class I have the following...
attr_accessible :name, :email, :password, :password_confirmation, :language, :remember_me, :profile_attributes, :admin, :slug
And that in my config file I have
config.active_record.whitelist_attributes = false #not standard nor recommended I know
I had the same problem and was able to get around it by separating out validates_uniqueness_of by itself. So for me
validates :username, :presence, uniqueness: { case_sensitive: false }
throws the same error (undefined method 'text?'). while changing to
validates_presence_of :username
validates_uniqueness_of :username, { case_sensitive: false }
works just fine.
I have this Rails 3.2 application running fine. I installed Rolify by following the steps below:
Add gem "rolify" to the Gemfile
Run bundle install
Run rails g rolify:role
Check the new migrations, the new files and the modified files (generated/modified by the command above).
Run rake db:migrate
At this point, I try to create/edit a User and I get the following error:
NoMethodError in UsersController#create
undefined method `user_id' for #<User:0x007f8f21f168e8>
Note that before I installed Rolify, everything was working fine, so the problem comes from Rolify.
Here are the migration, the new file and the modified file in question:
The new migration:
class RolifyCreateRoles < ActiveRecord::Migration
def change
create_table(:roles) do |t|
t.string :name
t.references :resource, :polymorphic => true
t.timestamps
end
create_table(:users_roles, :id => false) do |t|
t.references :user
t.references :role
end
add_index(:roles, :name)
add_index(:roles, [ :name, :resource_type, :resource_id ])
add_index(:users_roles, [ :user_id, :role_id ])
end
end
The new model:
class Role < ActiveRecord::Base
has_and_belongs_to_many :users, :join_table => :users_roles
belongs_to :resource, :polymorphic => true
end
The modified model:
class User < ActiveRecord::Base
rolify
has_secure_password
has_many :issues
acts_as_tenant(:client)
attr_accessible :email, :password, :password_confirmation, :username
validates :username, presence: true,
length: { within: 4..50 },
format: { with: /(?:[\w\d]){4,255}/ }
validates_uniqueness_to_tenant :username, case_sensitive: false
validates :email, presence: true,
uniqueness: { case_sensitive: false },
length: { within: 8..255 },
format: { with: /^[-a-z0-9_+\.]+\#([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i }
validates :password, presence: true, on: :create,
confirmation: true,
length: { within: 4..255 }
validates :password_confirmation, presence: true, on: :create
# NOTE: Used by SimpleForm to display the dropdown proerply
def to_label
"#{username}"
end
end
You can find the rest of the files in the project in the Github repo
Does anyone have a clue where the error comes from please?
This error is happening because the acts_as_tenant is (mistakenly) creating a validation for a user_id field on your User model. You can see this validator if you run this code inside rails c:
User._validators
I would recommend to switch to the apartment gem which appears to be more maintained than acts_as_tenant.
In attempting to seed my database I ran into a validation error on my User model's email attribute. The error:
Validation failed: Email is too short (minimum is 5 characters), Email is invalid
The thing is, my email is xxxxxxxx#gmail.com. I have five characters. Sorry for the beginner question but I don't know what is going on. I recently followed Railscasts to reset a User's password, and enable CanCan. I'm not sure if CanCan would affect anything, but prior to exploring that new functionality I've been able to fully seed my database without problems. I've pasted in some of my code below. I'm running Rails 3.0.5 and Ruby 1.9.2.
An example of how I create a User in my seed file:
me = User.create(:email => 'me#gmail.com', :password => 'test', :profile => my_profile)
User.rb model:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :password, :password_confirmation
before_save :encrypt_new_password
before_create { generate_token(:auth_token) }
before_validation :downcase_email
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
validates :email, :uniqueness => true,
:length => { :within => 5..50 },
:format => { :with => /^[^#][\w.-]+#[\w.-]+[.][a-z]{2,4}$/i }
validates :password, :confirmation => true,
:length => { :within => 4..20 },
:presence => true,
:if => :password_required?
Add :email to attr_accessible to allow mass assignment on it. Without that the email field will not even be set so validation will fail.
What is the difference between validates :presence and validates_presence_of? Looking through ActiveModel it looks like they setup the validation the same way. However, given the following model definition:
class Account < ActiveRecord::Base
has_one :owner_permission, :class_name => 'AccountPermission', :conditions => { :owner => true, :admin => true }
has_one :owner, :class_name => 'User', :through => :owner_permission, :source => :user
validate :owner, :presence => true
validates_associated :owner
end
Calling save on an instance of Account does not validate the presence of owner. Though, if I use validates_presence_of it will.
All those validates_whatever_of :attr macros do is call validates :attr, :whatever => true.
The problem is you are using validate and not validates.
In Rails 3.x and 4.x - it is now encouraged to use the following syntax:
validates :email, presence: true
validates :password, presence: true
Instead of the 2.x way:
validates_presence_of :email
validates_presence_of :password
In fact validates and validates_presence_of is not entirely equal !
validates_presence_of is allowing you to also lazily check by example of the value in the field is included in another table.
Like that:
validates_presence_of :pay_type, :inclusion => PaymentType.names
Which is something you can't do as easily with something like that
validates :pay_type, presence, :inclusion => PaymentType.names
Cause the inclusion is only evaluated the first time (not in a lazy way)
I would have thought that it is appropriate to use validates :foo presence: true when you want to include other validations of :foo such as length or uniqueness. But if you know the only validation you'll need for an attribute is presence, then validates_presence_of appears to be more efficient.
So:
validates :foo, length: {maximum: 50}, uniqueness: true,
format: {with: /bar/},
presence: true # lots of validations needed
But:
validates_presence_of :foo # only presence validation needed