# Validates\_each

**URL:** <https://www.ruby-forum.com/t/validates-each/128787>\
**Category:** Rails\
**Created:** [February 11, 2008, 3:56pm UTC](https://www.ruby-forum.com/t/validates-each/128787 "2008-02-11T15:56:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 11, 2008, 3:56pm UTC](https://www.ruby-forum.com/t/validates-each/128787/1 "2008-02-11T15:56:09Z")

</div>

Hi all,

I am trying to do a little checking before a user profile is created and  
see if some fields are blank. If they, that’s OK, I just need to set  
them to a dummy value if they are, not blank. The reason for this is  
that later on on another profile page they can change the value if the  
user wants through a edit\_in\_place helper, but that doesn’t do much good  
if the fields are blank. I have this validates\_each, and while the  
method gets executed correctly, I need it to set some of the variables  
for the User object which this method is a part of, but I am unsure on  
how to do that. This is what I have tried but it doesn’t work.

validates\_each :company :on =\> :save do|record, attr, value|  
if value.blank?  
value = “Click to Edit”  
self.attr = value  
end  
end

Any sujestions? Thanks,

-S

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 11, 2008, 8:51pm UTC](https://www.ruby-forum.com/t/validates-each/128787/2 "2008-02-11T20:51:09Z")

</div>

The example Ryan B. uses looks like:

validates\_presence\_of :state, :if =\> :in\_us?

def in\_us?  
country == ‘US’  
end

have a look at this if you get a minute →

> **[\#41 Conditional Validations - RailsCasts](http://railscasts.com/episodes/41-conditional-validations)**
>
> Short Ruby on Rails screencasts containing tips, tricks and tutorials. Great for both novice and experienced web developers.

I’m sure you can piece together a conditional validation from what he  
explains in the webcast.

On Feb 11, 9:56 am, Shandy N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 11, 2008, 10:03pm UTC](https://www.ruby-forum.com/t/validates-each/128787/3 "2008-02-11T22:03:36Z")

</div>

ebrad wrote:

> The example Ryan B. uses looks like:
> 
> validates\_presence\_of :state, :if =\> :in\_us?
> 
> def in\_us?  
> country == ‘US’  
> end

The problem with that is that I have many, many fields that I need to  
check which is why the way that I have I like so much, because it looped  
through each field in just a few lines of code. The way that I had it  
before was a huge method with a bunch of if’s checking to see which  
fields were blank - it was sloppy and ugly, which is why I tried to find  
a better way to do it. The problem with the way that I have now is that  
I can’t set each field to another via this validation. Thanks,

-S

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 12, 2008, 7:47pm UTC](https://www.ruby-forum.com/t/validates-each/128787/4 "2008-02-12T19:47:06Z")

</div>

@Shandy: You only want to use the validates\_xxx methods for validation  
(error checking), not for assignment. The simplest route to go might  
be to alter your db fields and provide default values for the  
attributes in question. You should do that through a migration so  
that you don’t lose visibility to the assignments in your code base.

Otherwise, consider something like this:

class MyModel  
DEFAULTS = {:attr1=\>default\_1, :attr2=\>default\_2, … }  
before\_create :set\_defaults  
…  
private  
def set\_defaults  
DEFAULTS.each do |attr, default\_value|  
self.send(“#{attr}=”, default\_value) unless  
self.send(attr).blank?  
end  
end  
end

Defaults is a hash of attributes (the keys) and their default values.  
You iterate over that and the loop assigns the default value if it  
finds the attribute blank.

On Feb 11, 4:03 pm, Shandy N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 12, 2008, 8:28pm UTC](https://www.ruby-forum.com/t/validates-each/128787/5 "2008-02-12T20:28:50Z")

</div>

AndyV wrote:

> The simplest route to go might  
> be to alter your db fields and provide default values for the  
> attributes in question. You should do that through a migration so  
> that you don’t lose visibility to the assignments in your code base.

That is what I ended up doing. It just seemed like the capability was  
there to do it the way I was trying but maybe not. Thanks for the help,

-S

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 15, 2008, 8:51pm UTC](https://www.ruby-forum.com/t/validates-each/128787/6 "2008-02-15T20:51:03Z")

</div>

AndyV wrote:

> class MyModel  
> DEFAULTS = {:attr1=\>default\_1, :attr2=\>default\_2, … }  
> before\_create :set\_defaults  
> …  
> private  
> def set\_defaults  
> DEFAULTS.each do |attr, default\_value|  
> self.send("#{attr}=", default\_value) unless  
> self.send(attr).blank?  
> end  
> end  
> end

I tried to get this to work and I’m not sure what I am doing wrong but  
it doesn’t. Everything prints out ok but nothing gets set. I am saying  
before\_save, that’s is the only difference in code. Any suggestions of  
what I am doing wrong? Thx,

-S

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 16, 2008, 6:57pm UTC](https://www.ruby-forum.com/t/validates-each/128787/7 "2008-02-16T18:57:39Z")

</div>

Sorry about that. In my mind I was thinking about assigning the  
values ahead of time so they’d be present in the form. As you figured  
out, I should have used an ‘if’ instead of an ‘unless’. Good catch!

On Feb 15, 3:36 pm, Shandy N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![snantz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@snantz](https://www.ruby-forum.com/u/snantz)\
**Post date:** [February 15, 2008, 9:36pm UTC](https://www.ruby-forum.com/t/validates-each/128787/8 "2008-02-15T21:36:15Z")

</div>

AndyV wrote:

> class MyModel  
> DEFAULTS = {:attr1=\>default\_1, :attr2=\>default\_2, … }  
> before\_create :set\_defaults  
> …  
> private  
> def set\_defaults  
> DEFAULTS.each do |attr, default\_value|  
> self.send("#{attr}=", default\_value) unless  
> self.send(attr).blank?  
> end  
> end  
> end

I answered my own question. I changed the unless self.send(attr).blank?  
part. I did this:

def set\_defaults  
DEFAULTS.each do |attr, default\_value|  
if self.send(attr).blank?  
self.send("#{attr}=", default\_value)  
puts attr  
puts default\_value  
end  
end  
end

But thanks for the help Andy, this is exactly what I was looking for.

-S
