Reputation: 6246
I'm very new to rails and am wondering what the best way to do this is:
I have a controller creating a record in the database.
If a specific validation error occurs I want to set a flag, and I can't see a good way to accomplish this with the rails patterns I am familiar with.
The models validation that I want to detect is:
validates_uniqueness_of :title
My controller is doing this:
fcs = Entity.create(:title => text)
When the above error fails I have an ActiveModel errors collection to work with.
How should I go about reliably setting a flag to indicate programatically that the title has been taken?
So far I've considered
fcs.errors.messages.has_key?(:title)
But this will return true if title has failed for some other reason. So I would need something more like:
fcs.errors.messages[:title]==["has already been taken"]
But that would be a maintenance headache and would also be broken by different locales...
So does anyone know how this should be done with RoR?
Thanks for any advice
edit: Example usage of proposed flag "is_title_duplicated":
if(! fcs.errors.empty?)
json['success']=false
json['errors']=fcs.errors.full_messages
json['title_was_duplicate'] = is_title_duplicated
render :json => json
...
Upvotes: 0
Views: 329
Reputation: 2331
I recommend adding a method to your model class to detect uniqueness.
class Entity < ActiveRecord::Base
def unique_title?
Entity.where(:title => title).count > 0
end
end
Of course, this would mean that you're running that query twice (once for the validates_uniqueness_of
and once for unique_title?
). I prefer readability over performance as long as the performance is acceptable. If the performance is not acceptable, you still have options. You can re-use unique_title?
in your own custom validation and cache the result.
class Entity < ActiveRecord::Base
validate :title_must_be_unique
def unique_title?
# you may want to unset @unique_title when title changes
if @unique_title.nil?
@unique_title = Entity.where(:title => title).count > 0
end
@unique_title
end
private
def title_must_be_unique
unless unique_title?
errors.add(:title, I18n.t("whatever-the-key-is-for-uniqueness-errors"))
end
end
end
Upvotes: 2
Reputation: 4622
Do you mean set a flag on the record? Whenever a validation fails the record is not saved to the database
If you just mean setting the error message, you don't have to. Rails will automatically set fsc.erros to be a hash that looks like {:title => "title has already been taken"}. You can specify that message by passing :message to your validation.
Also, you can internationalize the messages by using l18n. Just edit the yaml file as described here: http://guides.rubyonrails.org/i18n.html#configure-the-i18n-module
Upvotes: 1