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 (in `p')

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

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

Fred, thanks for your reply.

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

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?