在模型Venue
中,我将位置数据存储为Geocoder对象,当创建Geocoder.search
时,该对象通过Venue
从文本输入中获取。属于Geocoder::Result::Google
类的位置数据对象已序列化并保存在text
表的venues
列中。
class Venue < ActiveRecord::Base
serialize :location
before_validation :get_location
def get_location
return false unless venue_text
self.location = Geocoder.search(venue_text).first
end
end
首次在Rails控制台中创建对象时
2.3.0 :001 > Venue.create(venue_text: 'Madison Square Garden, New York City, New York')
(0.1ms) begin transaction
SQL (0.8ms) INSERT INTO "venues" ("venue_text", "location", "time_zone", "name", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["venue_text", "Madison Square Garden, New York City, New York"], ["location", "--- !ruby/object:Geocoder::Result::Google\ndata:\n address_components:\n - long_name: '4'\n short_name: '4'\n types:\n - street_number\n - long_name: Pennsylvania Plaza\n short_name: Pennsylvania Plaza\n types:\n - route\n - long_name: Manhattan\n short_name: Manhattan\n types:\n - political\n - sublocality\n - sublocality_level_1\n - long_name: New York\n short_name: New York\n types:\n - locality\n - political\n - long_name: New York County\n short_name: New York County\n types:\n - administrative_area_level_2\n - political\n - long_name: New York\n short_name: NY\n types:\n - administrative_area_level_1\n - political\n - long_name: United States\n short_name: US\n types:\n - country\n - political\n - long_name: '10001'\n short_name: '10001'\n types:\n - postal_code\n formatted_address: 4 Pennsylvania Plaza, New York, NY 10001, USA\n geometry:\n location:\n lat: 40.7505045\n lng: -73.9934387\n location_type: APPROXIMATE\n viewport:\n northeast:\n lat: 40.7518534802915\n lng: -73.99208971970849\n southwest:\n lat: 40.7491555197085\n lng: -73.9947876802915\n place_id: ChIJhRwB-yFawokR5Phil-QQ3zM\n types:\n - establishment\n - point_of_interest\n - stadium\ncache_hit: \n"], ["time_zone", "America/New_York"], ["name", "Madison Square Garden"], ["created_at", "2017-03-26 02:46:47.808170"], ["updated_at", "2017-03-26 02:46:47.808170"]]
(12.4ms) commit transaction
=> #<Venue id: 1, name: "Madison Square Garden", team_id: nil, venue_text: "Madison Square Garden, New York City, New York", location: #<Geocoder::Result::Google:0x00000003994dc0 @data={"address_components"=>[{"long_name"=>"4", "short_name"=>"4", "types"=>["street_number"]}, {"long_name"=>"Pennsylvania Plaza", "short_name"=>"Pennsylvania Plaza", "types"=>["route"]}, {"long_name"=>"Manhattan", "short_name"=>"Manhattan", "types"=>["political", "sublocality", "sublocality_level_1"]}, {"long_name"=>"New York", "short_name"=>"New York", "types"=>["locality", "political"]}, {"long_name"=>"New York County", "short_name"=>"New York County", "types"=>["administrative_area_level_2", "political"]}, {"long_name"=>"New York", "short_name"=>"NY", "types"=>["administrative_area_level_1", "political"]}, {"long_name"=>"United States", "short_name"=>"US", "types"=>["country", "political"]}, {"long_name"=>"10001", "short_name"=>"10001", "types"=>["postal_code"]}], "formatted_address"=>"4 Pennsylvania Plaza, New York, NY 10001, USA", "geometry"=>{"location"=>{"lat"=>40.7505045, "lng"=>-73.9934387}, "location_type"=>"APPROXIMATE", "viewport"=>{"northeast"=>{"lat"=>40.7518534802915, "lng"=>-73.99208971970849}, "southwest"=>{"lat"=>40.7491555197085, "lng"=>-73.9947876802915}}}, "place_id"=>"ChIJhRwB-yFawokR5Phil-QQ3zM", "types"=>["establishment", "point_of_interest", "stadium"]}, @cache_hit=nil>, time_zone: "America/New_York", created_at: "2017-03-26 02:46:47", updated_at: "2017-03-26 02:46:47">
我可以立即获得位置对象
2.3.0 :002 > Venue.first.location
Venue Load (0.3ms) SELECT "venues".* FROM "venues" ORDER BY "venues"."id" ASC LIMIT 1
=> #<Geocoder::Result::Google:0x0000000b71bed8 @data={"address_components"=>[{"long_name"=>"4", "short_name"=>"4", "types"=>["street_number"]}, {"long_name"=>"Pennsylvania Plaza", "short_name"=>"Pennsylvania Plaza", "types"=>["route"]}, {"long_name"=>"Manhattan", "short_name"=>"Manhattan", "types"=>["political", "sublocality", "sublocality_level_1"]}, {"long_name"=>"New York", "short_name"=>"New York", "types"=>["locality", "political"]}, {"long_name"=>"New York County", "short_name"=>"New York County", "types"=>["administrative_area_level_2", "political"]}, {"long_name"=>"New York", "short_name"=>"NY", "types"=>["administrative_area_level_1", "political"]}, {"long_name"=>"United States", "short_name"=>"US", "types"=>["country", "political"]}, {"long_name"=>"10001", "short_name"=>"10001", "types"=>["postal_code"]}], "formatted_address"=>"4 Pennsylvania Plaza, New York, NY 10001, USA", "geometry"=>{"location"=>{"lat"=>40.7505045, "lng"=>-73.9934387}, "location_type"=>"APPROXIMATE", "viewport"=>{"northeast"=>{"lat"=>40.7518534802915, "lng"=>-73.99208971970849}, "southwest"=>{"lat"=>40.7491555197085, "lng"=>-73.9947876802915}}}, "place_id"=>"ChIJhRwB-yFawokR5Phil-QQ3zM", "types"=>["establishment", "point_of_interest", "stadium"]}, @cache_hit=nil>
但是如果我从Rails控制台退出并执行相同的操作,那么该类是未定义的。
2.3.0 :001 > Venue.first.location
Venue Load (0.2ms) SELECT "venues".* FROM "venues" ORDER BY "venues"."id" ASC LIMIT 1
ArgumentError: undefined class/module Geocoder::Result::Google
我认为,由于我的应用程序上安装了geocoder
gem,应用程序应该能够识别和定义gem附带的类和方法。实际上,我能够在Geocoder.search
方法中使用get_location
没有问题。我在这里缺少什么?
答案 0 :(得分:0)
Ruby反序列化可能会绕过Rails覆盖的const_missing
方法来实现其魔力。您是否尝试在文件顶部添加requires 'geocoder'
?