Merge branch 'master' into notes
[rails.git] / app / models / old_relation.rb
1 class OldRelation < ActiveRecord::Base
2   include ConsistencyValidations
3   
4   self.table_name = "relations"
5   self.primary_keys = "relation_id", "version"
6
7   # note this needs to be included after the table name changes, or
8   # the queries generated by Redactable will use the wrong table name.
9   include Redactable
10
11   belongs_to :changeset
12   belongs_to :redaction
13   belongs_to :current_relation, :class_name => "Relation", :foreign_key => "relation_id"
14
15   has_many :old_members, :class_name => 'OldRelationMember', :foreign_key => [:relation_id, :version], :order => :sequence_id
16   has_many :old_tags, :class_name => 'OldRelationTag', :foreign_key => [:relation_id, :version]
17   
18   validates_associated :changeset
19
20   def self.from_relation(relation)
21     old_relation = OldRelation.new
22     old_relation.visible = relation.visible
23     old_relation.changeset_id = relation.changeset_id
24     old_relation.timestamp = relation.timestamp
25     old_relation.relation_id = relation.id
26     old_relation.version = relation.version
27     old_relation.members = relation.members
28     old_relation.tags = relation.tags
29     return old_relation
30   end
31
32   def save_with_dependencies!
33
34     # see comment in old_way.rb ;-)
35     save!
36     clear_aggregation_cache
37     clear_association_cache
38     @attributes.update(OldRelation.where(:relation_id => self.relation_id, :timestamp => self.timestamp).order("version DESC").first.instance_variable_get('@attributes'))
39
40     # ok, you can touch from here on
41
42     self.tags.each do |k,v|
43       tag = OldRelationTag.new
44       tag.k = k
45       tag.v = v
46       tag.relation_id = self.relation_id
47       tag.version = self.version
48       tag.save!
49     end
50
51     self.members.each_with_index do |m,i|
52       member = OldRelationMember.new
53       member.id = [self.relation_id, self.version, i]
54       member.member_type = m[0].classify
55       member.member_id = m[1]
56       member.member_role = m[2]
57       member.save!
58     end
59   end
60
61   def members
62     unless @members
63       @members = Array.new
64       OldRelationMember.where(:relation_id => self.relation_id, :version => self.version).order(:sequence_id).each do |m|
65         @members += [[m.type,m.id,m.role]]
66       end
67     end
68     @members
69   end
70
71   def tags
72     unless @tags
73       @tags = Hash.new
74       OldRelationTag.where(:relation_id => self.relation_id, :version => self.version).each do |tag|
75         @tags[tag.k] = tag.v
76       end
77     end
78     @tags = Hash.new unless @tags
79     @tags
80   end
81
82   def members=(s)
83     @members = s
84   end
85
86   def tags=(t)
87     @tags = t
88   end
89
90   def to_xml
91     doc = OSM::API.new.get_xml_doc
92     doc.root << to_xml_node()
93     return doc
94   end
95
96   def to_xml_node
97     el1 = XML::Node.new 'relation'
98     el1['id'] = self.relation_id.to_s
99     el1['visible'] = self.visible.to_s
100     el1['timestamp'] = self.timestamp.xmlschema
101     if self.changeset.user.data_public?
102       el1['user'] = self.changeset.user.display_name
103       el1['uid'] = self.changeset.user.id.to_s
104     end
105     el1['version'] = self.version.to_s
106     el1['changeset'] = self.changeset_id.to_s
107     
108     el1['redacted'] = self.redaction.id.to_s if self.redacted?
109     
110     self.old_members.each do |member|
111       e = XML::Node.new 'member'
112       e['type'] = member.member_type.to_s.downcase
113       e['ref'] = member.member_id.to_s # "id" is considered uncool here as it should be unique in XML
114       e['role'] = member.member_role.to_s
115       el1 << e
116     end
117     
118     self.old_tags.each do |tag|
119       e = XML::Node.new 'tag'
120       e['k'] = tag.k
121       e['v'] = tag.v
122       el1 << e
123     end
124
125     return el1
126   end
127
128   # Temporary method to match interface to nodes
129   def tags_as_hash
130     return self.tags
131   end
132
133   # Temporary method to match interface to relations
134   def relation_members
135     return self.old_members
136   end
137
138   # Pretend we're not in any relations
139   def containing_relation_members
140     return []
141   end
142
143   # check whether this element is the latest version - that is,
144   # has the same version as its "current" counterpart.
145   def is_latest_version?
146     current_relation.version == self.version
147   end
148 end