Railsify relation selection (aka ripping out the f***in SQL).
authorTom Hughes <tom@compton.nu>
Tue, 24 Jun 2008 23:42:39 +0000 (23:42 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 24 Jun 2008 23:42:39 +0000 (23:42 +0000)
app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/models/node.rb
app/models/relation.rb
app/models/way.rb
lib/object_finder.rb [new file with mode: 0644]

index 359b45326b99137b89bfaaba944959b15a45d503..11ddc3f7c7ba8fe9148fc4e9f65ae3ec47948d86 100644 (file)
@@ -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
index 26cb93a489cbd1f625b79ea727e0e58b78eccabf..9cf8977d332de0bfbf246ca126308cc1192160e2 100644 (file)
@@ -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.
index be444bf3e252fee4832ea12e8c31dfa4124d9742..abfa44d676930d3310e4c0b73fc8bcc9bad194e5 100644 (file)
@@ -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
index 71ddc4a554f0e696b83187d1df5014bade7946c3..bdba25f8f50c148a4a85d669ba96ddfe72dda408 100644 (file)
@@ -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
index 8ae6b40846944a41dca2ac03c542824fbb68fea1..a77f35fe9f7e7a4ed0ebbcb9ba229727abfa9f0f 100644 (file)
@@ -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 (file)
index 0000000..26608a7
--- /dev/null
@@ -0,0 +1,5 @@
+module ObjectFinder
+  def visible
+    find :all, :conditions => "#{proxy_reflection.table_name}.visible = 1"
+  end
+end