# One-time script to update 1000s of values in a single column in a table: nil error?

**URL:** <https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317>\
**Category:** Rails\
**Created:** [March 18, 2010, 3:27am UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317 "2010-03-18T03:27:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 3:27am UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/1 "2010-03-18T03:27:35Z")

</div>

Hi, I have a model called Stock with a value called “strength.” I  
wrote a simple method in the Stock.rb model file to update the value  
of “strength” for each record in the stocks table. I created a  
controller called fix\_controller.rb. I don’t have access to the live  
system, so the idea is that an admin will go to [http://url/fix](http://url/fix) and a  
script will run to check and potentially update the “strength” value  
for every record in the stocks table.

fix\_controller.rb  
^^^^^^^^^^^^^^^  
class FixController \< ApplicationController

def index  
stocks = Stock.find(:all)

```
stocks.each do |s|
    if s.strength.nil? || s.strength == ''
      puts 'nothing to update'
    else
      s.update_units
    end
end

```

end  
end

Stock.rb  
^^^^^^^^^  
def update\_units  
if self.strength == ‘’ || self.strength.nil?  
puts ‘nil - cannot update’  
elsif self.strength != ‘’ && self.strength != nil  
self.strength = self.strength.gsub!(’ ml’, ‘ml’) if  
self.strength.gsub!(’ ml’, ‘ml’) != nil  
self.strength = self.strength.gsub!(’ mL’, ‘ml’) if  
self.strength.gsub!(’ mL’, ‘ml’) != nil  
self.strength = self.strength.gsub!(’ g’, ‘g’) if self.strength.gsub!  
(’ g’, ‘g’) != nil  
self.strength = self.strength.gsub!(’ oz’, ‘oz’) if  
self.strength.gsub!(’ oz’, ‘oz’) != nil  
self.strength = self.strength.gsub!(’ mg’, ‘mg’) if  
self.strength.gsub!(’ mg’, ‘mg’) != nil  
end

When I try to run this, I always get the error:

NoMethodError: private method `gsub’ called for nil:NilClass

I’m sure this is a simple error and/or I’m not going about this the  
correct way. I really only need to run this code once… Any idea why  
I’m getting that error? I’m checking for nil…

---

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 5:31am UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/2 "2010-03-18T05:31:04Z")

</div>

it looks like you are trying to strip a leading space from each  
“strength” value if its not nil.

something like

stocks = Stock.find(:all, :conditions =\> ‘(strength IS NOT NULL) AND  
(strength != “”)’)

would give you all the stocks values with non-blank values. So you can  
skip a lot of your testing above.

You could then do something like

stocks.each do |stock|  
stock.strength = stock.strength.to\_s.gsub(/^\s+/,’’)  
stock.save  
end

the above is using a regular expression to match the leading spaces.  
the to\_s shouldn’t be necessary, because you should only be dealing  
with non-nil strength values at this point, but it’s defensive coding.

rails has a string extension .blank? which returns true for empty or  
nil or spaces values, e.g.

nil.blank?  
[].blank?  
" ".blank?  
‘’.blank?

all return true

---

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 9:44am UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/3 "2010-03-18T09:44:29Z")

</div>

On 18 March 2010 02:26, Clay H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Stock.rb  
> ^^^^^^^^^  
> self.strength = self.strength.gsub!(’ ml’, ‘ml’) if

The “gsub bang” method returns nil if no changes are made: it’s a  
method for changing string variables in place, not really for  
assigning the return value (unless you’re using the return value to  
check whether any replacements were made.

Change to:

---

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 1:03pm UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/4 "2010-03-18T13:03:32Z")

</div>

On 18 March 2010 02:26, Clay H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> correct way. I really only need to run this code once… Any idea why  
> I’m getting that error? I’m checking for nil…

As you only need to run this once it might be better as a database  
migration

If you leave it as an action it should really be a POST. Otherwise  
google may come along and ‘fix’ it for you while scanning your site.

Colin

---

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 1:20pm UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/5 "2010-03-18T13:20:31Z")

</div>

What exactly does the “…in place” part of that mean?

---

<div class="post-metadata">

**Author:** ![Clay\_H](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/958977/32.png) [@Clay\_H](https://www.ruby-forum.com/u/Clay_H)\
**Post date:** [March 18, 2010, 1:46pm UTC](https://www.ruby-forum.com/t/one-time-script-to-update-1000s-of-values-in-a-single-column-in-a-table-nil-error/185317/6 "2010-03-18T13:46:51Z")

</div>

On 18 March 2010 12:18, Clay H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What exactly does the “…in place” part of that mean?
> 
> On Mar 18, 4:42 am, Michael P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > The “gsub bang” method returns nil if no changes are made: it’s a  
> > method for changing string variables in place, not really for  
> > assigning the return value (unless you’re using the return value to  
> > check whether any replacements were made.

If you assign a value to a variable:

my\_variable = “100 mg”  
you can alter the variable using the bang method without using an =  
operator to assign  
so :  
my\_variable = my\_variable.gsub(’ mg’, ‘mg’)  
is the same as:  
my\_variable.gsub!(’ mg’, ‘mg’)  
but beware of:  
my\_variable = my\_variable.gsub!(’ mg’, ‘mg’)  
as if no substitution is made, the new value of my\_variable will be  
“nil” (as you discovered 😉

[http://ruby-doc.org/core/classes/String.html#M000817](http://ruby-doc.org/core/classes/String.html#M000817)
