scopeValidationvalidatesNot null and not empty stringConditional validatesuniquenessinclusioncallbackbefore_validationRelated Articles
scope
- scope is just like macro: allows you to specify commonly-used queries which can be referenced as method calls on the association objects or models
class Book < ApplicationRecord
scope :out_of_print, -> { where(out_of_print: true) }
end
irb> Book.out_of_print
=> #<ActiveRecord::Relation> # all out of print books
Validation
class Book < ActiveRecord::Base
belongs_to :subject
validates_presence_of :title
validates_numericality_of :price, :message=>"Error Message"
end
validates
class User < ApplicationRecord
validates :name, presence: true
end
irb> user = User.new
irb> user.save
=> false
irb> user.save!
# ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
Not null and not empty string
class User < ApplicationRecord
validates :name, presence: true, allow_blank: false
end
Conditional validates
class User < ApplicationRecord
validates :name, presence: true, unless: -> { is_alvin == true }
end
uniqueness
The column should be unique and no duplicate.
class Account < ApplicationRecord
validates :email, uniqueness: true
end
Also, with
scope
, make them a combination:class Holiday < ApplicationRecord
validates :name, uniqueness: { scope: :year,
message: "should happen once per year" }
end
A combination of
country
and medium
is unique.class AddUniqueIndexToReleases < ActiveRecord::Migration
def change
add_index :releases, [:country, :medium], unique: true
end
end
class Release < ActiveRecord::Base
validates :country, uniqueness: { scope: :medium }
end
inclusion
class Coffee < ApplicationRecord
validates :size, inclusion: { in: %w(small medium large),
message: "%{value} is not a valid size" }
end
callback
- Callbacks are mainly used around object lifecycle such as create, update, destroy, and etc
- X_Y
- X:
before
,after
, andaround
- Y:
create
,update
,save
,commit
,destroy
,rollback
# from https://stackoverflow.com/questions/27932270/how-does-an-around-action-callback-work-an-explanation-is-needed
begin
# Do before action...
logger.info 'I am the before action'
# Do the action, which is passed as a block to your "around filter"
# Note that if you were to delete this line, the action will never be called!
yield
# Do after action...
logger.info 'I am the after action'
ensure
raise ActiveRecord::Rollback
end
before_validation
Is called before
Validations.validate
(which is part of the Base.save
call).# trigger a method
class User < ApplicationRecord
validates :name, presence: true
before_validation :callback_name
def callback_name
# do something
end
end
# trigger a block
class User < ApplicationRecord
validates :login, :email, presence: true
before_create do
self.name = login.capitalize if name.blank?
end
end
# trigger a proc
class User < ApplicationRecord
before_create ->(user) { user.name = user.login.capitalize if user.name.blank? }
end
# trigger a custom callback object
class User < ApplicationRecord
before_create MaybeAddName
end
class MaybeAddName
def self.before_create(record)
if record.name.blank?
record.name = record.login.capitalize
end
end
end