From def60c193514a0d5067d5c0b007421e1a472b73b Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 24 Jun 2008 23:42:39 +0000 Subject: [PATCH] Railsify relation selection (aka ripping out the f***in SQL). --- app/controllers/amf_controller.rb | 4 +++- app/controllers/api_controller.rb | 12 +++--------- app/models/node.rb | 2 +- app/models/relation.rb | 25 +------------------------ app/models/way.rb | 2 +- lib/object_finder.rb | 5 +++++ 6 files changed, 14 insertions(+), 36 deletions(-) create mode 100644 lib/object_finder.rb diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 359b45326..11ddc3f7c 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -123,7 +123,9 @@ class AmfController < ApplicationController points = nodes_not_used_in_area.collect { |n| [n.id, n.lon_potlatch(baselong,masterscale), n.lat_potlatch(basey,masterscale), n.tags_as_hash] } # find the relations used by those nodes and ways - relation_ids = (Relation.find_for_nodes_and_ways(nodes_in_area.collect {|n| n.id}, way_ids)).collect {|n| n.id}.uniq + relations = nodes_in_area.collect { |node| node.containing_relations.visible }.flatten + + way_ids.collect { |id| Way.find(id).containing_relations.visible }.flatten + relation_ids = relations.collect { |relation| relation.id }.uniq [way_ids,points,relation_ids] end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 26cb93a48..9cf8977d3 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -124,8 +124,6 @@ class ApiController < ApplicationController return end - relations = Array.new - doc = OSM::API.new.get_xml_doc # get ways @@ -170,19 +168,15 @@ class ApiController < ApplicationController end end - relations = Relation.find_for_nodes_and_ways(visible_nodes.keys, way_ids) + relations = visible_nodes.values.collect { |node| node.containing_relations.visible }.flatten + + way_ids.collect { |id| Way.find(id).containing_relations.visible }.flatten # we do not normally return the "other" partners referenced by an relation, # e.g. if we return a way A that is referenced by relation X, and there's # another way B also referenced, that is not returned. But we do make # an exception for cases where an relation references another *relation*; # in that case we return that as well (but we don't go recursive here) - relation_ids = relations.collect { |relation| relation.id } - if relation_ids.length > 0 - relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " + - "e.visible=1 and " + - "em.id = e.id and em.member_type='relation' and em.member_id in (#{relation_ids.join(',')})") - end + relations += relations.collect { |relation| relation.containing_relations.visible }.flatten # this "uniq" may be slightly inefficient; it may be better to first collect and output # all node-related relations, then find the *not yet covered* way-related ones etc. diff --git a/app/models/node.rb b/app/models/node.rb index be444bf3e..abfa44d67 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -18,7 +18,7 @@ class Node < ActiveRecord::Base has_many :ways, :through => :way_nodes has_many :containing_relation_members, :class_name => "RelationMember", :as => :member - has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation + has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation, :extend => ObjectFinder # Sanity check the latitude and longitude and add an error if it's broken def validate_position diff --git a/app/models/relation.rb b/app/models/relation.rb index 71ddc4a55..bdba25f8f 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -11,7 +11,7 @@ class Relation < ActiveRecord::Base has_many :relation_tags, :foreign_key => 'id' has_many :containing_relation_members, :class_name => "RelationMember", :as => :member - has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation + has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation, :extend => ObjectFinder def self.from_xml(xml, create=false) begin @@ -105,29 +105,6 @@ class Relation < ActiveRecord::Base return el1 end - - # collect relationships. currently done in one big block at the end; - # may need to move this upwards if people want automatic completion of - # relationships, i.e. deliver referenced objects like we do with ways... - # FIXME: rip out the fucking SQL - def self.find_for_nodes_and_ways(node_ids, way_ids) - relations = [] - - if node_ids.length > 0 - relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " + - "e.visible=1 and " + - "em.id = e.id and em.member_type='node' and em.member_id in (#{node_ids.join(',')})") - end - if way_ids.length > 0 - relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " + - "e.visible=1 and " + - "em.id = e.id and em.member_type='way' and em.member_id in (#{way_ids.join(',')})") - end - - relations # if you don't do this then it returns nil and not [] - end - - # FIXME is this really needed? def members unless @members diff --git a/app/models/way.rb b/app/models/way.rb index 8ae6b4084..a77f35fe9 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -13,7 +13,7 @@ class Way < ActiveRecord::Base has_many :way_tags, :foreign_key => 'id' has_many :containing_relation_members, :class_name => "RelationMember", :as => :member - has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation + has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation, :extend => ObjectFinder def self.from_xml(xml, create=false) begin diff --git a/lib/object_finder.rb b/lib/object_finder.rb new file mode 100644 index 000000000..26608a7f9 --- /dev/null +++ b/lib/object_finder.rb @@ -0,0 +1,5 @@ +module ObjectFinder + def visible + find :all, :conditions => "#{proxy_reflection.table_name}.visible = 1" + end +end -- 2.43.2