I have 2 fields:
attr_accessible :in_home #=> boolean, setted at false by default
mount_uploader :carousel_picture, CarouselUploader#=>an image picture with CarrierWave + Rmagick. Nil by default
attr_accessible :carousel_picture
My question is: I try to validate the fact that when the user checks the "in_home" checkbox, he should have uploaded a "carousel_picture"
validates :in_home, :if => Proc.new { |obj| (obj.in_home && obj.carousel_picture?) == true }, :presence => {:message => "You should upload a carousel picture to set the item in the home page."},
But this validation doesn't work, I can create an object with the in_home checked and the carousel_picture empty.
When I try after in my rails console:
1.9.3p362 :001 > obj = MyObject.all.last
=> #<Gift id: 22, name: "foo", created_at: "2013-04-02 09:13:00", updated_at: "2013-04-02 09:13:00", carousel_picture: nil, in_home: true>
1.9.3p362 :002 > obj.in_home && obj.carousel_picture?
=> false
So I think there is something that I don't understand in how I do a validation of a field. Any help would be useful!
Thank you in advance
Try this,
validates_presence_of :carousel_picture, :if => lambda {|obj| obj.in_home == true}
I was trying to do something similar recently, I think the below code should work for you:
validates :carousel_picture, :presence => { :if => Proc.new { |a| a.in_home? }, message: "You should upload a carousel picture to set the item in the home page." }
Related
I have in my model
class Account < ActiveRecord::Base
validates_length_of :amount, :in 1..255, :on => update, :if => Proc.new { |a| false if a.id == nil;a.amount.blank? }
validates_length_of :name, :in 1..255, :on => update, :if => Proc.new { |a| false if a.id == nil;a.name.blank? }, :unless => user_has_amount?
end
when I comment out the if condition, it works fine but with them validation fails which is confusing. I know that the validation should only run if the proc returns true or unless returns false
in my controller I have
#account.update_attributes({:name => "king", :amount => "1223"}
the save fails and when I check errors I get
#account.errors.details
{:name =>[{:error=>:too_short, :count=>1}], :amount =>[{:error=>:too_short, :count=>1}]}
Strong Params are not an issue because I have
def self.params
params.require(:account).permit!
end
I have no idea why it fails though the value are present and correct.
Try this the following:
class Account < ActiveRecord::Base
validates :amount, length: { in: 1..255 }, on: :update
validates :name, length: { in: 1..255 }, on: :update
end
Check your strong parameters. Your error tells you that something is wrong before you get to validation: :name =>[{:error=>:too_short, :count=>1}] This is saying that the minimum string count is 1 but that your string is not even that long. Here is the docs on that.
You can try: Account.find(1).update_attributes({:name => "king", :amount => "1223"} to see if #account is not being set properly.
You can also customize the language on your errors to help further:
validates_length_of : name, within: 1..255, too_long: 'pick a shorter name', too_short: 'pick a longer name'
The issue that was happening was for one reason. The code was inheriting from a class that had:
slef.reload
in one of the function that were being called during validations.
so every time we try to update the update failed because once that validation was hit it reloaded the original values from database and ignored new values which if old values are empty is just a head scratcher.
Thanks everyone for the help
I'm trying to validate that an attribute is a boolean, i.e. true or false.
From the Rails guide I expected
validates :new_out_of_stock, inclusion: { in: [true, false] }
to work, but it accepts non-boolean values (e.g. "Hi") as valid:
irb> ip = ItemPrice.new
irb> ip.new_out_of_stock = "Hi"
=> "Hi"
irb> ip.valid?
=> true
irb> ip.errors.messages
=> {}
It correctly rejects nil and accepts true and false.
All the documentation on the Internet that I've read says that this is the correct way to validate a boolean attribute. Why doesn't it work?
Edit: Here's the class definition:
class ItemPrice < ActiveRecord::Base
belongs_to :item, counter_cache: true
validates :new_out_of_stock, inclusion: { in: [true, false] }
end
I think that non-boolean values are coerced to booleans when they're assigned to the attribute, causing them to pass the validation.
See:
irb> ip.new_out_of_stock
=> nil
irb> ip.new_out_of_stock = "hi"
=> "hi"
irb> ip.new_out_of_stock
=> false
and clearly false is a valid boolean value, so the field passes.
It's not accept non-boolean values (e.g. "Hi") as valid, you just need to do this:
irb> ip.new_out_of_stock="Hi"
=> "Hi"
irb> ip.valid?
=> false # so it's not accept "Hi"
irb> ip.errors.full_messages
=> ["New_out_of_stock is not included in the list"]
irb> ip.errors.messages
=> {:new_out_of_stock=>["is not included in the list"]}
irb> ip.errors.messages[:new_out_of_stock]
=> ["is not included in the list"]
UPDATE:
Try this in your model:
validate :require_boolean
def require_boolean
errors.add(:new_out_of_stock, "is not included in the list") unless self.new_out_of_stock.in?([true, false])
end
Try to change the syntax slightly to the following
validates :new_out_of_stock, :inclusion => {:in => [true, false]}
This has worked for me in the past
I am getting this error when when I try to validate. I am trying to validate whether if the string is not in the DB.
this is my model
class Location < Locations::Location
validate do
#strong URL check for url_prefix
errors.add(:url_prefix, "URL already taken") if self.url_prefix.valid? && is_on_web;
end
end
Instead use,
validates :url_prefix, :uniqueness => { :message => "URL already taken and is online" }
update:
conditional validation can be added to solve your second problem like this,
validates :url_prefix, :uniqueness => { :message => "URL already taken and is online" }, :if => :is_on_web?
I'm trying to set up my model in Rails 3.2.8 such that particular values must be present, but are allowed to be the empty string. Does anyone know how to do this?
The behavior I'm looking for looks like:
#foo.value = "this is a real value"
#foo.valid? # => true
#foo.value = nil
#foo.valid? # => false
#foo.value = ""
#foo.valid? # => true
If I use
validates :foo, :presence => true
then I get what I want for 1 and 2, but not 3. And, helpfully, :allow_blank => true is ignored when validating presence.
I also tried
validates :foo, :length => { :minimum => 0 }, :allow_nil => false
Same behavior: get what I want for 1 and 2, but not 3.
I suppose I could just mark the column as NOT NULL in the database, but then I have to deal with catching the exception; I'd really rather catch this at the validation stage.
Any ideas?
I would try something like this:
validates :foo, presence: true, unless: lambda { |f| f.foo === "" }
This one really has me. I have this validation in my user model:
validates :first_class, :presence => true, :inclusion => %w(Fighter Ranger Magician)
Now, I try an example create in my console:
ruby-1.9.2-p180 :053 > new = User.create(:first_class => 'Magician')
=> #<User id: nil, ...
ruby-1.9.2-p180 :054 > new.errors
=> {:first_class=>["can't be blank", "is not included in the list"]}
Why am I getting this validation error? I SERIOUSLY cannot figure that out.
(If i remove the validation, the user gets created, but first_class is nil :O)
maybe try having attr_accessible :first_class in your model file
You have to tell rails which attributes are writeable through mass-assignment. The new method takes a parameters hash, which is considered mass-assignment. The same is true with update_attributes.
To verify, you could just make a new instance and say object.first_class = 'Magician'. If this also fails, then you know attr_accessible is not the problem.