validates_numericality_of :latitude, :longitude
validate :validate_position
- has_many :ways, :through => :way_nodes
+ belongs_to :user
+
has_many :old_nodes, :foreign_key => :id
+
has_many :way_nodes
- belongs_to :user
-
+ has_many :ways, :through => :way_nodes
+
+ has_many :containing_relation_members, :as => :member
+ has_many :containing_relations, :through => :containing_relation_members
+
# Sanity check the latitude and longitude and add an error if it's broken
def validate_position
errors.add_to_base("Node is not in the world") unless in_world?
class Relation < ActiveRecord::Base
require 'xml/libxml'
+ set_table_name 'current_relations'
+
belongs_to :user
+ has_many :old_relations, :foreign_key => 'id', :order => 'version'
+
has_many :relation_members, :foreign_key => 'id'
has_many :relation_tags, :foreign_key => 'id'
- has_many :old_relations, :foreign_key => 'id', :order => 'version'
-
- set_table_name 'current_relations'
+ has_many :containing_relation_members, :as => :member
+ has_many :containing_relations, :through => :containing_relation_members
def self.from_xml(xml, create=false)
begin
class RelationMember < ActiveRecord::Base
set_table_name 'current_relation_members'
-
- # problem with RelationMember is that it may link to any one
- # object (a node, a way, another relation), and belongs_to is
- # not flexible enough for that. So we do this, which is ugly,
- # but fortunately rails won't actually run the SQL behind that
- # unless someone really accesses .node, .way, or
- # .relation - which is what we do below based on member_type.
- # (and no: the :condition on belongs_to doesn't work here as
- # it is a condition on the *referenced* object not the
- # *referencing* object!)
- belongs_to :node, :foreign_key => "member_id"
- belongs_to :way, :foreign_key => "member_id"
- belongs_to :relation, :foreign_key => "member_id"
+ belongs_to :member, :polymorphic => true, :foreign_type => :member_class
+ belongs_to :relation, :foreign_key => :id
+
+ def after_find
+ self[:member_class] = self.member_type.capitalize
+ end
- # so we define this "member" function that returns whatever it
- # is.
-
- def member()
- return (member_type == "node") ? node : (member_type == "way") ? way : relation
+ def after_initialize
+ self[:member_class] = self.member_type.capitalize
end
- # NOTE - relations are SUBJECTS of memberships. The fact that nodes,
- # ways, and relations can be the OBJECT of a membership,
- # i.e. a node/way/relation can be referenced throgh a
- # RelationMember object, is NOT modelled in rails, i.e. these links
- # have to be resolved manually, on demand.
+ def before_save
+ self.member_type = self[:member_class].downcase
+ end
+
+ def member_type=(type)
+ self[:member_type] = type
+ self[:member_class] = type.capitalize
+ end
end
class Way < ActiveRecord::Base
require 'xml/libxml'
+ set_table_name 'current_ways'
+
belongs_to :user
- has_many :nodes, :through => :way_nodes, :order => 'sequence_id'
+ has_many :old_ways, :foreign_key => 'id', :order => 'version'
+
has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id'
- has_many :way_tags, :foreign_key => 'id'
+ has_many :nodes, :through => :way_nodes, :order => 'sequence_id'
- has_many :old_ways, :foreign_key => 'id', :order => 'version'
+ has_many :way_tags, :foreign_key => 'id'
- set_table_name 'current_ways'
+ has_many :containing_relation_members, :class_name => "RelationMember", :as => :member
+ has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation
def self.from_xml(xml, create=false)
begin