For a project, I need the categories attribute of the Post class to be either "Fiction" or "Non-Fiction." I attempted the following syntax...
class CategoryValidator < ActiveModel::Validator
def validate(record)
unless (record.category == "Fiction" || "Non-Fiction")
record.errors[:category] << "Must be valid category"
binding.pry
end
end
end
but it never hit the binding.pry line, meaning it never hit "until" block, even when I entered purposefully wrong answers. What would the proper syntax for the #validate method be?
Your condition to check if the category is either 'Fiction'
or 'Non-Fiction'
isn't right.
(record.category == "Fiction" || "Non-Fiction")
is evaluated as (record.category == "Fiction") || "Non-Fiction"
(record.category == "Fiction") || "Non-Fiction"
since ==
has higher precedence than ||
. As a result, the expression will always return "Non-Fiction"
which is truthy. That's why your code never got to the binding.pry
line even when the category wasn't "valid".
def validate(record)
unless %w(Fiction Non-Fiction).include?(record.category)
record.errors[:category] << "Must be valid category"
end
end
A custom validator is an overkill for this use-case. You can use inclusion
to add this validation.
validates :category, inclusion: {
in: %w(Fiction Non-Fiction),
message: 'must be either Fiction or Non-Fiction'
}
I hate myself, such a simple fix and I got it
class CategoryValidator < ActiveModel::Validator
def validate(record)
unless (record.category == "Fiction" || record.category == "Non-Fiction")
record.errors[:category] << "Must be valid category"
end
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.