I just updated from rails 2.3 to 3, i'm trying to replace this old method with something cleaner, because it's outputting the model and field name, wtf!
However I get the above error when calling validates_uniqueness_of (the presence works fine). I passed in the primary id scope, and still get it. Any help is welcome.
def validate
if org_name.blank?
errors.add(:org_name, :blank, :default => nil)
else
if (org = Organization.find_by_org_name(org_name)) && org != self
errors.add(:org_name, :taken, :default => nil, :value => org_name)
end
end
end
to
validates :org_name, :presence => true
validates_uniqueness_of :org_name, :scope => :org_id
Ths is the Rails 3 syntax for uniqueness validtion:
validates :org_name, uniqueness: {scope: :org_id}
This is easy to fix.
Firstly, analyse the error message:
Org name translation missing:
en.activerecord.errors.models.user.attributes.org_name.blank
This is caused by the following line of code:
errors.add(:org_name, :blank, :default => nil)
When you call the above, you are telling rails to look for a translation whose key is :blank. You probably didn't set that up yet, so to do that, just go into your locales file (config/locales/en.yml), and add the following:
en:
hello: "Hello world"
activerecord:
errors:
models:
organization:
attributes:
org_name:
blank: "can't be blank."
Hopefully that will fix it for you.
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 new to RoR. I'm facing a problem when using validates_uniqueness_of. I've a table with 3 columns:
name || father_name || dob
Vimal Raj || Selvam || 1985-08-30
I've a code in my model like this:
class Candidate < ActiveRecord::Base
attr_accessible :dob, :father_name, :name
validates_uniqueness_of :name, scope: [:father_name, :dob], case_sensitive: false,
message: ": %{value} already present in the database!!!"
before_save :capitalize_name, :capitalize_father_name
private
def capitalize_name
self.name.capitalize!
end
def capitalize_father_name
self.father_name.capitalize!
end
end
It throws error as expected when I insert => "vimal raj, Selvam, 1985-08-30"
But it is accepting the following data => "Vimal Raj, selvam, 1985-08-30" . I was expecting it will throw an error, but unexpectedly it accepts the record and inserts into the db as a new record.
Please help me on how to solve this.
If you want a one-liner solution, please try this :
before_validation lambda {self.name.capitalize!; self.father_name.capitalize!}
Hope, it will help.
I think the case_sensitivity is only matching on name, not on father_name. I would try changing before_save to before_validation so that both name and father_name are consistently the same capitalization when your validation is evaluated.
I'm adding a validator inside the User.rb model to validate the birthdate given is over 18 years old before create the devise user.
This is the validation I have.
# user.rb
validates :birthdate, :before => lambda { 18.years.ago }, :before_message => "must be at least 18 years old"
Inside the User schema
# User schema
t.date "birthdate"
Problem is that I'm getting the following error when trying to save the object.
ArgumentError in Devise::RegistrationsController#create
Unknown validator: 'BeforeValidator'
Unknown validator: 'BeforeValidator' means you've overestimated the magic :)
Try this:
validate do |user|
if user.birthdate > 18.years.ago
errors.add(:birthdate, "must be at least 18 years old")
end
end
You can also try:
before_validation :validade_birth_date
private
def validade_birth_date
if (birthdate != nil)
errors.add(:birthdate, "must be at least 18 years old") unless (birthdate < DateTime.now)
end
end
:before is not an actual default validator of ActiveRecord. When validates finds any validator name it doesn't know, it searches one custom validator with its name (in this case BeforeValidation)
All validations are made before the actual object is stored by nature, and you don't have to make your own validator as pointed out. ActiveRecord already provides one: :numericality
validates :birthdate, :numericality => { :greater_than => 18 , :message => "must be at least %{count} years old" }
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.
hiho
Is there any way to tell rails that my string may not be 'something'?
I am searching for something like
validates :string, :not => 'something'
thanks
klump
Either of these will do the job (click on the methods for documentation):
Probably the best and fastest way, easy to extend for other words:
validates_exclusion_of :string, :in => %w[something]
This has a benefit of using a regexp, so you can generalise easier:
validates_format_of :string, :without => /\A(something)\Z/
You can extend to other words with /\A(something|somethingelse|somemore)\Z/
This is the general case with which you can achieve any validation:
validate :cant_be_something
def cant_be_something
errors.add(:string, "can't be something") if self.string == "something"
end
To get exactly the syntax you proposed (validates :string, :not => "something") you can use this code (a warning though, I discovered this while reading the master branch of the rails source and it should work, but it doesn't work on my ~ 3 months old install). Add this somewhere in your path:
class NotValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors[attribute] << "must not be #{options{:with}}" if value == options[:with]
end
end
A couple of ways. If you have exact list of what it can't be:
validates_exclusion_of :string, :in => ["something", "something else"]
If you want to ensure that it doesn't exist as a substring at all:
validates_format_of :string, :with => /\A(?!something)\Z/
If it is more complicated and you want to hide the messy details:
validate :not_something
def not_something
errors.add(:string, "Can't be something") if string =~ /something/
end