Validation fails on ":on => :save" - ruby-on-rails

I am using rails 3.0.10 and ruby 1.9.2p0
In my rails app I am trying to validate my model through a "validates_uniqueness_of"
In my model(label) there is field named as "name" and I want to validate it as:
validates_uniqueness_of :name, :scope => [:portal_id], :on => :save
Portal is another model in my app.
It validates perfectly when i use :on => :create or :update individually, but fails when i use :on => :save
any idea I want to validate on save, but AR validation fails.

As default all validations run before save.so no need to give :on => :save
Simply use
validates_uniqueness_of :name, :scope => [:portal_id]

Related

Skipping validation on create method

I need to skip the validation on create method.I am using Rails 4 and ruby 2
i have tried like this
#model.save(:validate => false)
it not working
Assuming you are talking about ActiveRecord; In Rails 3 and 4 the way to skip validations and potentially persist invalid objects is as you describe:
#model.save(:validate => false)
In Rails 2 you'd need to do
#model.save(false)
You can do this in model by
validates :some_attr, :presence => true, :on => :update
validates :some_attr, :presence => true, :unless => :create
skips the validation JUST for create.

In Rails, how can I only use validates_inclusion_of when the model is created, NOT every time it is updated?

I have an object, called Account, and there is a campaign source associated with every account. Currently, if the Account is updated, and there is no campaign source, you have to update the campaign source (the possible values of which are in a selectlist).
I know that validates_presence_of has an :on option, which allows you to specify :create, :update or :save, but validates_inclusion_of does not have this option, unfortunately. How can I get around this? Thanks.
Here is my code:
class Account < ActiveRecord::Base
validates_inclusion_of :campaign_source, :in => CampaignSource.list, :message => "^Please let us know how you heard about us"
Try
validates :campaign_source, :inclusion => { :in => CampaignSource.list },
:message => "^Please let us know how you heard about us",
:on => :create

Validate attribute only if it present (only if user fill in it)

I need validate some attributes ONLY if they are not empty.
For example the user may have a logo. If we try to load it - validation should work. If we simply update the user's data without the logo, validation must be skipped.
Now i have:
The form has a choice of two files. One - logo, second - avatar.
Both of this attributes is part of User model. In User model a have validation:
validates_preference_of :logo_file_name, :message=>I18n.t("...")
validates_format_of :logo_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("...")
validates_preference_of :avatar_file_name, :message=>I18n.t("...")
validates_format_of :avatar_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("...")
In this case, if we try to create a new User without selected logo and avatar, we will have errors (our validation). I tryed change validation and add ":on => :update" like this:
validates_preference_of :logo_file_name, :message=>I18n.t("..."), :on => :update
validates_format_of :logo_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("..."), :on => :update
validates_preference_of :avatar_file_name, :message=>I18n.t("..."), :on => :update
validates_format_of :avatar_file_name, :with=>/\.(jpeg|jpg|png|gif)$/i, :message=> I18n.t("..."), :on => :update
Now i can create user without selected logo and avatar, but if i try edit user and try upload only logo - i have validation errors of avatar. If i choose file for avatar and logo leave blank - i have validation errors for logo.
How i can run validation ony for attribute that I want to change?
Add :allow_blank => true and it should do what you want.
Some validations accept the options :allow_blank => true or :allow_nil => true.
If this fails, use :if condition, like this:
validates_format_of :avatar_file_name,
:with=>/\.(jpeg|jpg|png|gif)$/i,
:message=> I18n.t("..."),
:on => :update,
:if => lambda{ |object| object.avatar_file_name.present? }
But i encourage you to use allows. Much cleaner.
Maybe :if => lambda {|attr| attr.present?} will help?

Rails 3 & validate_on_create

Rails 3 warns me that validate_on_create is deprecated. I have def validate_on_create in one of my models. What do I replace it with?
You can use:
validates :name, :presence => true, :on => :create
If you have a method that performs validations, you should run as:
validate :method_name, :on => :create

How to update attributes without validation

I've got a model with its validations, and I found out that I can't update an attribute without validating the object before.
I already tried to add on => :create syntax at the end of each validation line, but I got the same results.
My announcement model have the following validations:
validates_presence_of :title
validates_presence_of :description
validates_presence_of :announcement_type_id
validate :validates_publication_date
validate :validates_start_date
validate :validates_start_end_dates
validate :validates_category
validate :validates_province
validates_length_of :title, :in => 6..255, :on => :save
validates_length_of :subtitle, :in => 0..255, :on => :save
validates_length_of :subtitle, :in => 0..255, :on => :save
validates_length_of :place, :in => 0..50, :on => :save
validates_numericality_of :vacants, :greater_than_or_equal_to => 0, :only_integer => true
validates_numericality_of :price, :greater_than_or_equal_to => 0, :only_integer => true
My rake task does the following:
task :announcements_expiration => :environment do
announcements = Announcement.expired
announcements.each do |a|
#Gets the user that owns the announcement
user = User.find(a.user_id)
puts a.title + '...'
a.state = 'deactivated'
if a.update_attributes(:state => a.state)
puts 'state changed to deactivated'
else
a.errors.each do |e|
puts e
end
end
end
This throws all the validation exceptions for that model, in the output.
Does anybody how to update an attribute without validating the model?
You can do something like:
object.attribute = value
object.save(:validate => false)
USE update_attribute instead of update_attributes
Updates a single attribute and saves the record without going through the normal validation procedure.
if a.update_attribute('state', a.state)
Note:- 'update_attribute' update only one attribute at a time from the code given in question i think it will work for you.
try using
#record.assign_attributes({ ... })
#record.save(validate: false)
works for me
Yo can use:
a.update_column :state, a.state
Check: http://apidock.com/rails/ActiveRecord/Persistence/update_column
Updates a single attribute of an object, without calling save.
All the validation from model are skipped when we use validate: false
user = User.new(....)
user.save(validate: false)
Shouldn't that be
validates_length_of :title, :in => 6..255, :on => :create
so it only works during create?

Resources