Reputation: 71
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
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
Reputation: 7146
Update from @travis
This would work only for a single value:
You can also use Active Record Validations acceptance
which receive an :accept
option 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