How to check emptiness on devise custom fields? - devise

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

Related

Rails nil value when saving to database

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

activeadmin habtm better example for uniqueness case

Am able to manage habtm as per follow, and I wanted a better way for this
I have habtm between User and Tag on Rails 3, aa 0.5.1
Tag name is uniq
f.input :tags, :label => 'Assign existing tag'
# this above allows to select from existing tags, but cannot allow to create one
f.has_many :tags, :label => 'Add new tags, modify existings' do |ff|
ff.input :name
ff.input :_destroy, :as => :boolean
end
# this above allows to create new one but not allow to specify existing one
# if we specify existing one, uniqueness wont let create this one, neither existing get used
# and throws validation error
any hints?
Adding my models
class User < ActiveRecord::Base
has_and_belongs_to_many :tags
scope :tagged_with, lambda {|tags| joins(:tags).where("tags.name" => tags)}
accepts_nested_attributes_for :tags, :allow_destroy => true
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :users
validates :name, :uniqueness => { :case_sensitive => false }
end
Try this,
f.label => 'Assign existing tag'
f.select :tags, Tag.all.map{|t| [t.tag_name, t.id]}, {:prompt => "Select Tag name" }
this above allows to select from existing tags, don't have option to create one
For the Second thing add this line in the model,
validates :tags, :uniqueness => {:scope => :tag_name}
here the :tag_name is your name of the fieldname. This throw an error if the tag name already exists when you create a duplicate.
It's just an idea as per your question. This won't be your exact answer because your specification is not enough to give you the exact answer.

Rails 3.2 + Rolify: Application breaks after installing Rolify (Bug?)

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.

Rails: validation fail for a nested model on key field presence check

I have a model User and a nested model Mobility
class User < ActiveRecord::Base
has_many :mobilities, :dependent => :destroy
accepts_nested_attributes_for :mobilities
end
and
class Mobility < ActiveRecord::Base
belongs_to :mobile_user, :class_name => 'User'
validates :city_id, :presence =>true
validates :user_id, :presence =>true
validates :city_id, :uniqueness => {:scope => [:user_id]}
end
my view
=form_for #user, :as => :user, :html =>{ :class => 'form-horizontal'} do |f|
=f.fields_for :mobilities do |city_form|
=city_form.text_field :city_id, :id => "city_id_#{index}"
= f.submit "Retour"
my problem is that when I submit the form Rails render me this validation error:
Mobilities user > doit ĂȘtre rempli(e)
But if a I comment this line:
#validates :user_id, :presence =>true
Both, my Mobility and User objects get saved and know what: user_id field of #mobility is OK (indicatie my #user's ID)
If I send the form with 2 identical mobility inside, both model get saved but it seems my validation of uniqueness didn't check nothing because i have 2 Mobility object with same user_id and city_id in my database...
In fact it seems like my validation can't read my user_id 's key when validating.
I understand that because my User model did'nt get saved yet and doesnt have any ID yet... but that is my question:
How can i check both: presence of user_id and uniqueness with scope ???

Rails 3: validates :presence => true vs validates_presence_of

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