Suppose there is a Rails model with a custom setter/accessor and a uniqueness constraint on the name
column:
class Person < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
def name=(name)
# Example transformation only.
# Could be substituted for a more complex operation/transformation.
title_cased = name.titleize
self[:name] = title_cased
end
end
Now, consider the following:
Person.create! name: "John Citizen"
Person.find_or_create_by! name: "john citizen" # Error: validation fails
The find
operation will not find any results, since there are no entries that match "john citizen". Then, the create!
operation will throw an error as there is already an existing entry "John Citizen" (create!
creates a new record and raises an exception if the validation fails).
How do you elegantly prevent such errors from occurring? For loose coupling and encapsulation purposes, is it possible to not transform names (to titlecase, in this case) before I perform operations like find_or_create_by!
or other operations like find_by
?
EDIT: As @harimohanraj alludes to, the issue seems to be around equivalence. Should the model transparently deal with the understanding/translating input to its boiled-down, canonical state. Or should this be the responsibility of consumers of the class/model?
Also, is active record callbacks a recommended approach to this kind of scenario?