Mongomapper uniqueness - ruby-on-rails

I have user model
class User
include MongoMapper::Document
key :phone, Integer, :required => true, :unique => true
key :is_confirmed, Boolean, :default => false
timestamps!
end
and validate uniqueness of phone but i can create user with the same phone without error.WHY?
why validate uniqueness doesn't work

MongoMapper uses ActiveModel:Validations, so it works almost exactly like ActiveRecord
Try this to validate: validates_uniqueness_of
validates_uniqueness_of :phone
Validations are run when attempting to save a record. If validations fail, save will return false.
Most Simple Validations can be declared along with the keys.
Example:
class Person
include MongoMapper::Document
key :first_name, String, :required => true
key :last_name, String, :required => true
key :age, Integer, :numeric => true
key :born_at, Time
key :active, Boolean
key :fav_colors, Array
end
The available options when defining keys are:
:required – Boolean that declares validate_presence_of
:unique – Boolean that declares validates_uniqueness_of
:numeric – Boolean that declares validates_numericality_of
:format – Regexp that is passed to validates_format_of
:in – Array that is passed to validates_inclusion_of
:not_in – Array that is passed to validates_exclusion_of
:length – Integer, Range, or Hash that is passed to validates_length_of

Related

Minitest for testing presence and allow_nil for the same attribute

I want to test a model attribute where it has presence as true, but also allow nil value. How can I test this? I made an example bellow:
# Person model
belongs_to :city
validates :city_id, presence: true, :allow_nil => true
I was trying to test with:
test "should permit nil for city_id" do
#person.city_id = nil
assert #person.valid?
end
What I got in console:
Expected false to be truthy.
I found the answer. The test was failing because it was missing a argument in belongs_to:
# Person model
belongs_to :city, optional: true
validates :city_id, presence: true, :allow_nil => true
The argument Optional allows nil value to foreign key.

Rails Field Validation Based on Value of Another Field

I need to validate that the value of a field (:discount) is one of an array of strings. The :discount field can also be blank UNLESS the :type field is 'FixedDeal' (STI)
validates :discount, inclusion: {in: VALID_DISCOUNTS}, allow_blank: true unless :type == 'FixedDeal'
The above code works to validation the value of :discount, but allows the field to be blank even if the type is 'FixedDeal'.
On your FixedDeal class add the following validation:
validates_presence_of :discount
That should work for you.

Where do I put the database constraints in rails?

Simple problem. I'm learning RoR. I swear that I searched this theme here and in google.
I need a lot of tables in my app.
I'm reading about the benefits of database constraints. I'm using validations inside every model, example:
class Example < ActiveRecord::Base
belongs_to :other
has_one :another...
attr_accessible :username, :email, :password
validates :username, e:mail, :password, presence: true
validades .....
end
I would like to know about database constraints, how can i get the same validation inside the database? Should i put this constraints (like :null => false) inside the schema.rb file?
Yes, absolutely put that in your migration:
:null => false
To require a non-empty field. Although an empty string can still be supplied and it passes the non-NULL test. You can cover this by adding a length validation:
validates_length_of :username, :minimum => 1, :maximum => 255

Mongoid create new Users

I'm trying to write an example app using Ruby on Rails and the Mongoid Mapper.
For some kind of Testing I want to write 1000 Testusers into MongoDB...
With the code bolow Mongoid is not able to write unique uid's. In my ruby console i got the right number for the counter but not for the uid.
Does anybody know what I forgot?
class User
include Mongoid::Document
include Mongoid::Timestamps
def self.create_users
(1..1000).each do |f|
user = User.new(uid: f.to_s, first_name: "first_name", last_name: "last_name", e_mail: "e_mail")
user.save!
puts f
puts user.uid
end
end
field :uid, :type => String
field :first_name, :type => String
field :last_name, :type => String
field :e_mail, :type => String
field :messages, :type => String
attr_accessible :first_name, :last_name, :e_mail
validates_presence_of :uid, :first_name, :last_name, :e_mail
validates_uniqueness_of :uid
has_many :messages
end
You don't have to provide the field uid in your models. MongoId add the id field for you and manages the value during the create operation.
Simply remove field :uid, :type => String from model
If you want to use your own ids you can change the name of the uid field to _id and it should work just fine. However, the default generated mongo _id will make it easier to scale and using it removes one of the more difficult aspects of sharding if you ever need that feature.
If you want to use the ones that are generated by default, they are included automatically unless overridden explicitly (behavior which you have seen) so just remove your custom field and you should be all set.
You can read more about ObjectIds here.

problem with passing booleans to update_attributes

I've got the following Model:
class GuestCatering < ActiveRecord::Base
# Validation
validates :name, :presence => true
validates :order_number, :presence => true
validates :orderable, :presence => true
end
But when I'll try to update an existing GuestCatering with the following code:
guest_catering.update_attributes(:orderable => false)
The guest catering variable is a valid GuestCatering object.
The guest_catering object has errors after the update, like that:
<{[:orderable, ["can't be blank"]]=>nil}>
But when i pass a orderable => true, everything is fine and no errors.
What's wrong here, why can't i set orderable to false?
Your model is actually behaving exactly as you told it to, through your use of validates :orderable, :presence => true
There's little point validating the presence of a boolean flag - it's going to be true, nil or false - and in Ruby world, nil and false have the same semantic value when it comes to boolean logic.
Internally, validates :presence relies on the value of the attribute being checked to return false when blank? is called. And, in Rails (with ActiveSupport), false.blank? evaluates as true - which means that your field is failing the validation.
Simply remove that validation and everything will work as expected.
Like Dan Cheail already said in his answer, a nil and false boolean is semantically the same thing.
But, if you really need to validate it (not allowing nil), you can always do :
validates_inclusion_of :orderable, :in => [true, false]
Instead of validates :presence => :true, you should write your migrations with the default value like this:
t.boolean :orderable, :default => 0
I assume your default value should be false. If true, use 1 as default. Then it will set the default value in database. So, you can omit the validation check.
The reason you cannot use validates :presence is answered by #dan. Presence means not blank and Rails use .blank? function for this and false.blank? is true

Resources