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(changeset_cache = {}, user_display_name_cache = {})
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     el1['version'] = self.version.to_s
102     el1['changeset'] = self.changeset_id.to_s
103
104     if changeset_cache.key?(self.changeset_id)
105       # use the cache if available
106     else
107       changeset_cache[self.changeset_id] = self.changeset.user_id
108     end
109
110     user_id = changeset_cache[self.changeset_id]
111
112     if user_display_name_cache.key?(user_id)
113       # use the cache if available
114     elsif self.changeset.user.data_public?
115       user_display_name_cache[user_id] = self.changeset.user.display_name
116     else
117       user_display_name_cache[user_id] = nil
118     end
119
120     if not user_display_name_cache[user_id].nil?
121       el1['user'] = user_display_name_cache[user_id]
122       el1['uid'] = user_id.to_s
123     end
124     
125     el1['redacted'] = self.redaction.id.to_s if self.redacted?
126     
127     self.old_members.each do |member|
128       e = XML::Node.new 'member'
129       e['type'] = member.member_type.to_s.downcase
130       e['ref'] = member.member_id.to_s # "id" is considered uncool here as it should be unique in XML
131       e['role'] = member.member_role.to_s
132       el1 << e
133     end
134     
135     self.old_tags.each do |tag|
136       e = XML::Node.new 'tag'
137       e['k'] = tag.k
138       e['v'] = tag.v
139       el1 << e
140     end
141
142     return el1
143   end
144
145   # Temporary method to match interface to nodes
146   def tags_as_hash
147     return self.tags
148   end
149
150   # Temporary method to match interface to relations
151   def relation_members
152     return self.old_members
153   end
154
155   # Pretend we're not in any relations
156   def containing_relation_members
157     return []
158   end
159
160   # check whether this element is the latest version - that is,
161   # has the same version as its "current" counterpart.
162   def is_latest_version?
163     current_relation.version == self.version
164   end
165 end