Rails model validation - validates_inclusion_of - ruby-on-rails

I am having torubles with my model.
I have the code:
class Typeofaid < ActiveRecord::Base
validates_inclusion_of :type, :in => %w(Food Water Health)
end
But whenever I type 'Food' etc in the box I get
`1 error prohibited this typeofaid from being saved:
* Type is not included in the list
`
Can anyone help?

I think you have to facturize your model using the type attribute instead of just entering some value using an input box.
"type" is a reserved column for single table inheritence in Rails.

Change it to the below code and try for it work fine for me in Rails3
validates :type, :inclusion => {:in => %w(Food Water Health)}

Related

How to validate presence of an array using Enumerize?

I'm trying to implement to validations on a given model array-like field, using the Enumerize Gem. I want to:
validate that all the elements of a list belong to a given subset, using Enumerize
validate that the list is not empty (using validates :field, presence: true)
It seems that when I provide a list containing an empty string, the presence validator fails. See this example.
class MyModel
include ActiveModel::Model
extend Enumerize
enumerize :cities, in: %w(Boston London Berlin Paris), multiple: true
validates :cities, presence: true
end
# Does not behave as expected
a = MyModel.new(cities: [""])
a.cities.present? # => false
a.valid? # => true, while it should be false.
It seems to work in some other cases (for instance when you provide a non empty string that is not in the Enum). For instance
# Behaves as expected
a = MyModel.new(cities: ["Dublin"])
a.cities.present? # => false
a.valid? # => false
Is there a workaround available to be able to use both Enumerize validation and ActiveModel presence validation?
Thanks!
The enumerize gem is saving your multiple values as an string array. Something like this: "[\"Boston\"]". So, with an empty array you have: "[]". The presencevalidator uses blank? method to check if the value is present or not. "[]".blank? returns false obviously.
So, you can try some alternatives:
Option 1:
validates :cities, inclusion: { in: %w(Boston London Berlin Paris) }
Option 2:
Add a custom validator
validate :ensure_valid_cities
def ensure_valid_cities
errors.add(:cities, "invalid") unless cities.values.empty?
end
This is actually a bug that should be fixed in a later version of Enumerize (See https://github.com/brainspec/enumerize/pull/226).
In the meantime, you can use a custom validator as a workaround (See Leantraxx's answer).

How to do a simple regex validation in rails

How can perform a reguler expression to validate for either - or _ in the person username. i dont want to accept any other character like .#()$etc just - or _ so the person can either have a name like mike, mikel_mark or mike-mark. very simple. Thank you
example:
validate_format_of :username, with: "...."
The Rails 3 way to do validations is the following:
validates :username, :format => {:with => /\A[0-9a-z_]+\Z/i}
The form of validate_format_of is more Rails < 3 like and followed the "type of validation" concept, whereas the validates form is attribute based (you write all validations that apply to the attribute in one statement).
Check out the docs here: http://apidock.com/rails/v3.2.13/ActiveModel/Validations/ClassMethods/validates

rails validate in model that value is inside array

I have a form where i pass a field named :type and i want to check if it's value is inside an array of allowed types so that no one is allowed to post not-allowed types.
the array looks like
#allowed_types = [
'type1',
'type2',
'type3',
'type4',
'type5',
'type6',
'type7',
etc...
]
i have tried using validates_exclusion_of or validates_inclusion_of but it doesn't seem to work
first, change the attribute from type to something else, type is a reserved attrubute name use for Single Table Inheritance and such.
class Thing < ActiveRecord::Base
validates :mytype, :inclusion=> { :in => #allowed_types }
ActiveModel::Validations provides a helper method for this. An example call would be:
validates_inclusion_of :type, in: #allowed_types
ActiveRecord::Base is already a ActiveModel::Validations, so there is no need to include anything.
http://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_inclusion_of
Also, #RadBrad is correct that you should not use type as a column name as it is reserved for STI.
Just for those lazy people (like me) to copy the latest syntax:
validates :status, inclusion: %w[pending processing succeeded failed]
validates_inclusion_of is out of date since Rails 3.
:inclusion=> hash syntax is out of date since Ruby 2.0.
In favor of %w for word array as the default Rubocop option.
With variations:
Default types as a constant:
STATUSES = %w[pending processing succeeded failed]
validates :status, inclusion: STATUSES
OP's original:
validates :mytype, inclusion: #allowed_types

Validating a existence of a beta code before creating a User

model: User
has_one :beta_invite
before_save :beta_code_must_exist
def beta_code_must_exist
if beta_invite_id == beta_invite.find_by_name(beta_invite.id)
user
else
nil
end
end
model: BetaInvite
has_many :users
What I`m trying to do is check for the existence of a beta invite in DB, before allowing the user to be saved.
Since the User will be passing in the BetaInvite name into the field, I would like to check if it matches any existing Codes in the DB.
Hope I didn`t mix things up too much.
Would appreciate any help with this problem.
Add a text field to the form for :beta_code
Add an attr_accessor for that field: attr_accessor :beta_code
Then add the following line to the model (Assumes you only want to do this check on user creation):
validate :beta_code_must_exist, :on => :create
Change beta_code_must_exist to add an error to the form. Also be sure to properly cast :beta_code into the correct type.
Warning untested code below
def beta_code_must_exist
#invite = BetaInvite.find_by_name(beta_code)
if #invite.empty?
errors.add(:beta_code, "is not a valid invite code")
else
beta_invite_id = #invite.id
end
end
Use :inclusion with the :in option. You can supply :in with any enumerable:
validates :beta_invite, :inclusion => { :in => BetaInvite.all,
:message => "%{value} is not a valid beta invite code" }
Source: Rails Active Record Validation

Rails equivalent to Django's "choices"

I know there is no real equivalent in Rails but my question is mostly about best practice...
In Django, if you want to limit a model field to a limited set of choices, you would do something like this (in your model):
COLOR_CHOICES = (('B', 'Blue'), ('R', 'Red'))
item_color = models.CharField(choices=COLOR_CHOICES)
From my (basic) understanding of Rails, I can achieve something similar, for example, by using a select tag in the forms dealing with adding/editing that model...
My question however is, where would it be appropriate to declare the "choices" hash (again I'm guessing here that a hash is what I need?). Basically I just want it to be easily re-usable in any forms where I might need to present those choices, and when it comes to validating at the model level.
Any help/tips would be appreciated!
On the validation side of things, probably validates_inclusion_of is what you need:
class Coffee < ActiveRecord::Base
validates_inclusion_of :size, :in => %w(small medium large),
:message => "%{value} is not a valid size"
end
As for generating the helper, you can try something like:
class Coffee < ActiveRecord::Base
##coffe_size = %w(small medium large)
validates_inclusion_of :size, :in => ##coffe_size,
:message => "%{value} is not a valid size"
def self.coffee_size_options
##coffe_size.map{ |z| [z,z]}
end
end
And then in some helper:
<%= select(:coffee, :size, Coffee.coffee_size_options) %>
You can simply use enum
class Coffee < ActiveRecord::Base
enum color: [ :blue, :red, :green ]
end
More information here : https://api.rubyonrails.org/v5.2.4.1/classes/ActiveRecord/Enum.html
2 years later, there's a better option: values_for
class Car < ActiveRecord::Base
attr_accessible :brand
values_for :brand, :has=>[:ford, :chevy, :dodge], :add=>[:constants]
def doStuff
# Now you can...
Car.brands # [:ford, :chevy, :dodge]
Car::BRAND_FORD # "ford"
myCar = Car.new(:brand=>Car::BRAND_FORD)
myCar.valid? # true
myCar.brand= "duck."
myCar.valid? # false
end
end

Resources