I tried posting this earlier via google-groups interface, but there
seems to be some silly glitch so that new topics started at
google-groups (as oppossed to ruby-forum) takes DAYS to appear on the
list (yet, replies work just fine?). I’ll delete my previous attempts
next Monday when they finally appear. Anyway, here’s my situation:
I tried to use Active Record outside of Rails to update a database. I’m
using the google-geocode gem to update latitude/longitude values for
rows that haven’t already been geocoded.
I just have two models (Property belongs_to :city and City has_many
:properties, so I can grab city.name using the fk
‘properties.city_id’). My loop (leaving out the boring details) went
something like this:
for p in Property.find(:all, :conditions => "latitude = ‘’ ")
address = p.number.to_s + " " + p.street + ", " + p.city.name +
p.state + p.zip
location = gg.locate address
p.latitude = location.latitude
p.longitude = location.longitude
p.save
end
I learned two hard lessons. First, Active Record takes it upon itself
to update ALL column values, not just the values explicitly set
(rationale being?). Second, I also learned that Active Record treats
MySQL’s tinyint(1) as Boolean, so Active Record just wiped out an
unrelated column’s values by setting them all to = 0 (not a very nice
thing to do).
AWDwR suggests using the find_by_sql method. Again, I’m doing a join
with a ‘cities’ table to get the city ‘name’ value. So now I try:
p = Property.find_by_sql(“select properties.id, number, street,
cities.name as city_name, zip, latitude, longitude from properties join
cities on properties.city_id=cities.id limit 1”)
But this doesn’t work at all. None of the column value methods work
(i.e. p.zip ‘method undefined’) and p.id returns a crazy value
(-607864132, when the attribute hash has “id”=>“2250838”).
So how the heck do I update ONLY the values I explicitly set without
Active Record munging data in other columns? I’d rather not change the
column type, I just want Active Record to leave it alone in it’s
generated UPDATE query, if I haven’t explicitly asked it to update that
column.