How to set new object fields with not-hash object in ActiveRecord?

Hi, everyone.
I am using Geokit and Geokit-Rails3 on Ruby on Rails 3.0.3 / Ruby
1.8.7.

My model Location (which acts_as_mappable) is often created with lat
and lng.

For avoiding repeating yourself, I tried to override initialize method
and try to use Geokit::LatLng.normalize (this method creates a LatLng
object from string/array/etc…), but the following codes does not
work, and show curious errors.

There are also tests using the original style (:lat=>…, :lng=>…)
and they works fine.
According to “p ll” in location.rb, ll is correct.

Thanks in advance.

– location.rb
class Location < ActiveRecord::Base
acts_as_mappable :default_units=>:kms, :default_formula=>:flat
attr_accessible :lat, :lng

def initialize(args)
begin
ll = Geokit::LatLng.normalize(args)
p ll
lat = ll.lat; lng = ll.lng
rescue
super
end
end
end

– a part of location_spec.rb
it “should make new Location from LatLng object” do
Location.create!(Geokit::LatLng.normalize(“35,135”)).lat.should
== 35
end

it "should make new Location from String" do
  Location.create!("35, 150").lat.should == 35
end

it "should make new Location from Array" do
  p Location.new([35,150])#.lat.should == 35
end

– errors (shortly)
NoMethodError: … while evaluationg nil.[]
NoMethodError: undefined method has_key?' for nil:NilClass (inp’)

Fred, thanks for your reply.

On Sat, Apr 30, 2011 at 12:29 AM, Frederick C.
[email protected] wrote:

For avoiding repeating yourself, I tried to override initialize method
– location.rb
super
end
This doesn’t actually set your attributes, it just creates 2 local
variables.
Moreover, you’re not (unless an exception is thrown) calling super, so
active record’s internal state isn’t setup correctly - somethig like
super(:lat => ll.lat, :lng => ll.lng) is probably alright.

Thanks, it passes the test.
super(in rescue) is called when the parameter is a normal hash, because
Geokit::LatLng.normalize throws an exception when it cannot make
LatLng object from the argument, and LatLng does not support a hash.

You probably also want to be careful of the case where the object is
being loaded from the database

Some sites warns that AR does not call initialize method on loading a
object
from DB. I just use my custom initialization on newly creating a object
from
a form input.

As long as I tested (just make a new object and load it), this method
works
without problem.
Is there possibility of some bugs? How can I test it?

== 35
– errors (shortly)
NoMethodError: … while evaluationg nil.[]
NoMethodError: undefined method has_key?' for nil:NilClass (in p’)


You received this message because you are subscribed to the Google G. “Ruby
on Rails: Talk” group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.


Haruka YAGNI
[email protected]

On Apr 29, 11:16am, Haruka YAGNI [email protected] wrote:

work, and show curious errors.
attr_accessible :lat, :lng

def initialize(args)
begin
ll = Geokit::LatLng.normalize(args)
p ll
lat = ll.lat; lng = ll.lng
rescue
super
end
This doesn’t actually set your attributes, it just creates 2 local
variables.
Moreover, you’re not (unless an exception is thrown) calling super, so
active record’s internal state isn’t setup correctly - somethig like
super(:lat => ll.lat, :lng => ll.lng) is probably alright.
You probably also want to be careful of the case where the object is
being loaded from the database

Fred