codecalypso
codecalypso

Reputation: 71

Rails model custom validation

I have an attribute (:book) in my database that I'd like to restrict to three different values >>> :classic, :modern, :historic

I want to create a custom validation, so that when it is created or updated, a user can't type in googly-moogly

book: classic
      modern
      historic

Upvotes: 4

Views: 147

Answers (2)

Travis
Travis

Reputation: 1523

In whatever model has the book attribute:

VALID_BOOKS = [:classic, :modern, :historic]

validate :has_valid_book

def has_valid_book
  return if VALID_BOOKS.include? book.to_sym
  errors.add :book, 'must be a valid book'
end

Edit

Thanks to MrYoshiji for pointing out this particular case can be simplified to

VALID_BOOKS = [:classic, :modern, :historic]

validates :book, inclusion: { in: VALID_BOOKS.map(&:to_s) }

I'll leave the more verbose example above in case your validations become more complex in the future (as often happens) and an actual method is required to solve the problem.

Upvotes: 4

Cyzanfar
Cyzanfar

Reputation: 7146

Update from @travis

This would work only for a single value:

You can also use Active Record Validations acceptance which receive an :acceptoption that determines the value that will be considered acceptance.

For example:

class library < ActiveRecord::Base
  validates :book, acceptance: { accept: 'some value' }
end

* end of update*

Check out the Rails Guide on Validations

Following the answer of @Travis and the comment of @MrYoshiji, You can also assign the values you accept to a constant VALID_BOOKS = [:classic, :modern, :historic]

Then set up your callback as such:

validates :book, inclusion: { in: VALID_BOOKS.map(&:to_s) }

Upvotes: 0

Related Questions