Use a polymorphic association to model relation members and add
associations for upward links from objects to relations that they are a part of.
This commit is contained in:
parent
a21824f754
commit
b527d27674
4 changed files with 40 additions and 35 deletions
|
@ -10,11 +10,16 @@ class Node < GeoRecord
|
|||
validates_numericality_of :latitude, :longitude
|
||||
validate :validate_position
|
||||
|
||||
has_many :ways, :through => :way_nodes
|
||||
has_many :old_nodes, :foreign_key => :id
|
||||
has_many :way_nodes
|
||||
belongs_to :user
|
||||
|
||||
|
||||
has_many :old_nodes, :foreign_key => :id
|
||||
|
||||
has_many :way_nodes
|
||||
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?
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
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
|
||||
|
|
|
@ -1,30 +1,23 @@
|
|||
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
|
||||
|
||||
# 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_find
|
||||
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 after_initialize
|
||||
self[:member_class] = self.member_type.capitalize
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
class Way < ActiveRecord::Base
|
||||
require 'xml/libxml'
|
||||
|
||||
belongs_to :user
|
||||
set_table_name 'current_ways'
|
||||
|
||||
has_many :nodes, :through => :way_nodes, :order => 'sequence_id'
|
||||
has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :way_tags, :foreign_key => 'id'
|
||||
belongs_to :user
|
||||
|
||||
has_many :old_ways, :foreign_key => 'id', :order => 'version'
|
||||
|
||||
set_table_name 'current_ways'
|
||||
has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :nodes, :through => :way_nodes, :order => 'sequence_id'
|
||||
|
||||
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
|
||||
|
||||
def self.from_xml(xml, create=false)
|
||||
begin
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue