# Create custom validation

**URL:** <https://www.ruby-forum.com/t/create-custom-validation/183803>\
**Category:** Rails\
**Created:** [February 20, 2010, 1:35pm UTC](https://www.ruby-forum.com/t/create-custom-validation/183803 "2010-02-20T13:35:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![aldoitalo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@aldoitalo](https://www.ruby-forum.com/u/aldoitalo)\
**Post date:** [February 20, 2010, 1:35pm UTC](https://www.ruby-forum.com/t/create-custom-validation/183803/1 "2010-02-20T13:35:04Z")

</div>

hi, i created a validation to prevent users to write text uppercase in  
my fields, i have writing the code on my class model like this:

#####################

validate :detect\_uppercase\_title, :detect\_uppercase\_description

private

#prevent users to write text uppercase, and reset field text to  
lowercase  
def detect\_uppercase\_title  
size\_letters = title.scan(/\w/).size  
size\_invalid = title.scan(/[A-Z]/).size  
if size\_invalid \> 0  
if (size\_letters / size\_invalid) \< 4 and size\_letters \> 10  
errors.add( :title,  
I18n.t(‘activerecord.errors.messages.uppercase’))  
write\_attribute(:title, title.downcase)  
end  
end  
end  
def detect\_uppercase\_description  
size\_letters = description.scan(/\w/).size  
size\_invalid = description.scan(/[A-Z]/).size  
if size\_invalid \> 0  
if (size\_letters / size\_invalid) \< 4 and size\_letters \> 10  
errors.add( :description,  
I18n.t(‘activerecord.errors.messages.uppercase’))  
write\_attribute(:description, description.downcase)  
end  
end  
end

#####################

but now i want to define a function to doing this without repeating and  
make more DRY the code.

i have tried with this:

#####################

validate detect\_uppercase(title), detect\_uppercase(description)

private

def detect\_uppercase(field)  
size\_letters = field.scan(/\w/).size  
size\_invalid = field.scan(/[A-Z]/).size  
if size\_invalid \> 0  
if (size\_letters / size\_invalid) \< 4 and size\_letters \> 10  
errors.add( field,  
I18n.t(‘activerecord.errors.messages.uppercase’))  
write\_attribute(field, field.downcase)  
end  
end  
end

#####################

but i see it not work.  
hw can i do to implement my necessity?

---

<div class="post-metadata">

**Author:** ![aldoitalo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@aldoitalo](https://www.ruby-forum.com/u/aldoitalo)\
**Post date:** [February 20, 2010, 3:01pm UTC](https://www.ruby-forum.com/t/create-custom-validation/183803/2 "2010-02-20T15:01:42Z")

</div>

Try this

def validates\_on\_yours\_method\_name  
size\_letters = field.scan(/\w/).size  
size\_invalid = field.scan(/[A-Z]/).size  
if size\_invalid \> 0  
if (size\_letters / size\_invalid) \< 4 and size\_letters \> 10  
errors.add( field,  
I18n.t(‘activerecord.errors.  
messages.uppercase’))  
write\_attribute(field, field.downcase)  
end  
end

end

On Sat, Feb 20, 2010 at 6:05 PM, Aldo I. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> lowercase  
> end  
> end  
> validate detect\_uppercase(title), detect\_uppercase(description)  
> I18n.t(‘activerecord.errors.messages.uppercase’))  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

–  
Thanks:  
Rajeev sharma

---

<div class="post-metadata">

**Author:** ![aldoitalo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@aldoitalo](https://www.ruby-forum.com/u/aldoitalo)\
**Post date:** [February 20, 2010, 5:49pm UTC](https://www.ruby-forum.com/t/create-custom-validation/183803/3 "2010-02-20T17:49:52Z")

</div>

i have resolved with this:

#prevent users to write text uppercase, and reset field text to  
lowercase  
validates\_each :title, :description do |model, attr, value|  
size\_letters = value.scan(/\w/).size  
size\_invalid = value.scan(/[A-Z]/).size  
if size\_invalid \> 0  
if (size\_letters / size\_invalid) \< 4 and size\_letters \> 10  
model.errors.add( attr,  
I18n.t(‘activerecord.errors.messages.uppercase’))  
model.write\_attribute(attr, value.downcase)  
end  
end  
end

for Hassan S.: i want the user write in uppercae only certain  
letters( itials of names, letter after points, etc…). with my solution  
i concur the user to write in the text the 25% of letters uppercase.

thanks to all.

---

<div class="post-metadata">

**Author:** ![aldoitalo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@aldoitalo](https://www.ruby-forum.com/u/aldoitalo)\
**Post date:** [February 20, 2010, 4:48pm UTC](https://www.ruby-forum.com/t/create-custom-validation/183803/4 "2010-02-20T16:48:49Z")

</div>

On Sat, Feb 20, 2010 at 4:35 AM, Aldo I. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> hi, i created a validation to prevent users to write text uppercase in  
> my fields, i have writing the code on my class model like this:

> #prevent users to write text uppercase, and reset field text to lowercase

Do you really need to “prevent” them, or can you just downcase it  
and be done? In any case, wouldn’t the easiest check be something  
like

unless ( field.downcase == field ) errors.add( … )

## ?

Hassan S. ------------------------ removed\_email\_address@domain.invalid  
twitter: @hassan
