Validates Presense VS Null False in Rails Models/Tables

Validates presense vs null false in Rails models/tables

Adding a :null => false means that this is a database restriction, i.e. under no circumstance will the database allow a null value.

Adding a presence: true is a model level validation so will take place before the object is inserted into the database. There may be a case you want to break these validations (for example edge cases or in your specs) You can then skip validation using :validates => false and the object will still go into the database, with a null DB restriction, this won't happen.

Presence:true vs. null:false in migration table

I guess it depends on what database you use and which keywords it supports.
So if a db that you use supports keyword 'presence:true', you can use it.

However the best practice is to use null:false, I've never seen anything other.

Plus, Rails has a special migration method for this case, and it's called change_column_null http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_column_null

Hope it's useful for you.

Should I add database constraints for null false and width if I have validations for these?

The short answer is that it depends and opinions vary. I tend to favor always having constraints in the database even if the code validates it. For the reason that developers, QA, etc. may attempt to inject data directly into the database. Having a constraint enforces the convention. See this Stack Exchange thread for more feedback.

Understanding rails migration statement (:null = false)

Edit: I had taken the question to be about syntax and translation since it originally mentioned CoffeeScript. For purpose, refer to Peter Bloom's answer.


I am not sure what the :null => false means exactly.

The => operator is a key/value separator in Ruby, defining a Hash with a :null key set to false. It's similar to : for an Object literal in CoffeeScript/JavaScript -- { null: false }.

When used in an argument list, it's one option for allowing/imitating named arguments in Ruby.

The other main difference is that CoffeeScript/JavaScript use Strings for keys while Ruby typically uses Symbols -- "null" (cs/js) vs. :null (rb).

So, the syntactic equivalent in CoffeeScript would be:

x.datetime "new",     null: false
x.datetime "update", null: false

In JavaScript, that's:

x.datetime("new",    { null: false });
x.datetime("update", { null: false });

Validate presence of field only if another field is blank - Rails

You don't need a lambda. This will do:

validates_presence_of :mobile_number, :unless => :home_phone?

Also, all of the validators take the same if/unless options, so you can make them conditional at will.

Update: Looking back at this answer a few days later, I see that I should explain why it works:

  • If you set a validator's :unless option to be a symbol, Rails will look for an instance method of that name, invoke that method on the instance that's being validated -- at validation time -- and only perform the validation if the method returns false.
  • ActiveRecord automatically creates question mark methods for each of your model's attributes, so the existence of a home_phone column in your model's table causes Rails to create a handy #home_phone? method. This method returns true if and only if home_phone is present (i.e. not blank). If the home_phone attribute is nil or an empty string or a bunch of white space, home_phone? will return false.

UPDATE: Confirmed that this old technique continues to work in Rails 5.

Rails and Model Validation

To validate the presence of an association, use its name, without _id appended:

validates_presence_of :library

It will validate two things:

  1. library_id is present
  2. a Library with the given id exists

Using validates_presence_of :library_id will only give you the first validation of the two.

In addition to this, the version without _id will also correctly validate if both records are new (and therefore library_id is still unset).

How to validate text isn't blank in Rails

Rails adds the handy method blank? which checks for false, nil and empty strings as described here.

Rails also adds the handy validator allow_blank: false.

So in your case it should be:

validates :body, presence: true, allow_blank: false


Edit (original answer above):

As stated in the answer below, allow_blank: false is not needed as that's the default behaviour of presence: true.

Rails: Validation in model vs migration

Wherever possible, validate at the database level as well as at the model level.

Why? For starters, active record does not enforce validation in all contexts. The following methods skip validations, and will save the object to the database regardless of its validity:

decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_counters

If you pass :validate => false to save, it will also skip validation. See the Active Record Validations and Callbacks Guide section on Skipping Validations for details. (If this worries you, there is even a gem for disabling these methods.)

So reason #1 is that Rails validations are not full-proof by any means: relying on them exclusively is risky, particularly for mission-critical validations such as uniqueness.

Speaking of which, reason #2 (off the top of my head): activerecord validations are prone to race conditions, and Rails' uniqueness validator in particular cannot guarantee uniqueness. Here's one article among many that documents why this is so.

Although they may be a rare occurrence, violations of uniqueness constraints can corrupt an entire data set. In the rare case that Rails is about to do this, you want at all costs to stop it, which is where the DB uniqueness constraint comes in: databases are built to handle this situation and will enforce uniqueness consistently, even when Rails does not.

And reason #3: why not validate both in the model and in the DB? Sure, you duplicate a bit, but that's generally a pretty minor concern compared with the payoff if Rails misses something like a uniqueness validation check. This is really not an either/or proposition: it's always better to duplicate validation in the DB wherever you can, particularly for mission-critical constraints such as uniqueness.

Anyway, those are my thoughts, hope that helps.

Ref: Where Correctness Is Enforced (screencast by Gary Bernhardt, need subscription to view)



Related Topics



Leave a reply



Submit