warren-GGWXsB6tJanpgkiH4x7ZXw@public.gmane.org
2009-Mar-14 21:24 UTC
Trouble consuming REST from OpenStreetMap - self-closing elements, perhaps?
I''m consuming openstreetmap.org''s REST api: http://wiki.openstreetmap.org/wiki/OSM_Protocol_Version_0.5#Retrieving_all_objects_in_a_bounding_box and I get an error when I try to run the following code in my ActiveResource model: # GET /api/0.5/map?bbox=left,bottom,right,top def self.features(left,bottom,right,top) find(:first, :from=>"/api/0.5/map?bbox=#{left},#{bottom},#{right},# {top}") end Yields: undefined method `collect!'' for #<Hash:0x22f2798> RAILS_ROOT: /Users/jeff/Desktop/whooz-osm/whooz-osm Application Trace | Framework Trace | Full Trace lib/active_resource/base.rb:595:in `instantiate_collection'' lib/active_resource/base.rb:559:in `find_every'' lib/active_resource/base.rb:508:in `find'' app/models/openstreetmap.rb:9:in `features'' I thought it was this patch, and perhaps it is, in a sense: http://dev.rubyonrails.org/ticket/8798 (that''s why i''m using my own copy of base.rb; i used their patch) But in fact, I think it may be because if you actually go to OSM''s response: http://api.openstreetmap.org/api/0.5/map?bbox=11.54,48.14,11.543,48.145 you see that they''re using self-closing elements, which aren''t ever used in REST examples, as far as I can tell. That is, they use: <node foo="bar" /> instead of always: <node> <foo>bar</foo> </node> Odd, since OSM is run on Rails anyways... so that gives me a Hash: {"node"=>[{"lon"=>"11.5411444", "user"=>"lesi", (...) ...in which "node" is the only node element. Looks like it''s not recognizing it as self-closing, and treating the rest of the xml as part of that element. In any case, it''s the following part of /active_resource/base.rb which is causing the problem: def instantiate_collection(collection, prefix_options = {}) # collection.collect! { |record| instantiate_record(record, prefix_options) } puts collection.inspect if collection.is_a?(Hash) && collection.size == 1 value = collection.values.first if value.is_a?(Array) value.collect! { |record| instantiate_record(record, prefix_options) } else [ instantiate_record(value, prefix_options) ] end else collection.collect! { |record| instantiate_record(record, prefix_options) } end end And I''m not sure how to patch AR to be able to read self-closing elements... i think it''s in /active_resource/formats/xml_format.rb, but it''s kind of opaque to me. Wonder if you have any thoughts on this? Are self-closing elements a valid expression of REST xml? Can I filter/reformat in my AR model, or should I extend whatever XML parser AR is using... rexml, i''d guess... to appropriately read this? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
warren-GGWXsB6tJanpgkiH4x7ZXw@public.gmane.org
2009-Mar-17 00:26 UTC
Re: Trouble consuming REST from OpenStreetMap - self-closing elements, perhaps?
FYI! My good friend Robert (http://www.robertsosinski.com/) responded with this excellent overview with which I got things running in about 20 lines of code: #################################################### Hey Jeff, You are dipping into one of the most interesting facets of REST, and that is what constitutes REST in terms of routing is up to heated debate. The REST that you are used to using with resource routing is really just the way that Rails has decided to use. At the end of the day, with REST the URL should just determine a resource, how it is formatted can be a bit dicy. Although OSM uses Rails, their routes are quite a bit off from normal Rails resource routes. This may be for a slew of reasons, one of which there being quite a few devs who have felt the short comings of terse http verb driven routes. Active Resource works pretty well when consuming from a textbook Rails RESTful API, however starts to become very constricting once there is a deviation from it. Also, Active Resource is honestly still a bit buggy, and I would not count on OSM''s xml to not be mal-formed (my experience is that API''s that are not consumed by the developers themselves are often lacking in maturity). This combination can make automagic Resource driven models problematic. One such example is running a Array#collect! method on a Hash, which is what Active Resource is doing for you, and thus yielding an error. The solution, well is to write your own wrapper. Thankfully this is pretty easy. I have had alot of success working with something called HTTParty (http://railstips.org/2008/7/29/it-s-an-httparty-and-everyone- is-invited) on github (http://github.com/jnunemaker/httparty). HTTParty is basically a gem that gives you an easy to use interface to Ruby''s HTTP object that is very API centric. The cool thing, is that the API does not expect Rails RESTful routes and you can specify how routes are interfaced with in a very granular way while HTTParty handles the parsing of xml/json input and redundant domain interface issues behind the scenes. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---