Merge remote-tracking branch 'upstream/pull/1827'
[rails.git] / app / models / old_node.rb
1 # == Schema Information
2 #
3 # Table name: nodes
4 #
5 #  node_id      :integer          not null, primary key
6 #  latitude     :integer          not null
7 #  longitude    :integer          not null
8 #  changeset_id :integer          not null
9 #  visible      :boolean          not null
10 #  timestamp    :datetime         not null
11 #  tile         :integer          not null
12 #  version      :integer          not null, primary key
13 #  redaction_id :integer
14 #
15 # Indexes
16 #
17 #  nodes_changeset_id_idx  (changeset_id)
18 #  nodes_tile_idx          (tile)
19 #  nodes_timestamp_idx     (timestamp)
20 #
21 # Foreign Keys
22 #
23 #  nodes_changeset_id_fkey  (changeset_id => changesets.id)
24 #  nodes_redaction_id_fkey  (redaction_id => redactions.id)
25 #
26
27 class OldNode < ActiveRecord::Base
28   include GeoRecord
29   include ConsistencyValidations
30   include ObjectMetadata
31
32   self.table_name = "nodes"
33   self.primary_keys = "node_id", "version"
34
35   # note this needs to be included after the table name changes, or
36   # the queries generated by Redactable will use the wrong table name.
37   include Redactable
38
39   validates :changeset, :presence => true, :associated => true
40   validates :latitude, :presence => true,
41                        :numericality => { :integer_only => true }
42   validates :longitude, :presence => true,
43                         :numericality => { :integer_only => true }
44   validates :timestamp, :presence => true
45   validates :visible, :inclusion => [true, false]
46
47   validate :validate_position
48
49   belongs_to :changeset
50   belongs_to :redaction
51   belongs_to :current_node, :class_name => "Node", :foreign_key => "node_id"
52
53   has_many :old_tags, :class_name => "OldNodeTag", :foreign_key => [:node_id, :version]
54
55   def validate_position
56     errors.add(:base, "Node is not in the world") unless in_world?
57   end
58
59   def self.from_node(node)
60     old_node = OldNode.new
61     old_node.latitude = node.latitude
62     old_node.longitude = node.longitude
63     old_node.visible = node.visible
64     old_node.tags = node.tags
65     old_node.timestamp = node.timestamp
66     old_node.changeset_id = node.changeset_id
67     old_node.node_id = node.id
68     old_node.version = node.version
69     old_node
70   end
71
72   def to_xml
73     doc = OSM::API.new.get_xml_doc
74     doc.root << to_xml_node
75     doc
76   end
77
78   def to_xml_node(changeset_cache = {}, user_display_name_cache = {})
79     el = XML::Node.new "node"
80     el["id"] = node_id.to_s
81
82     add_metadata_to_xml_node(el, self, changeset_cache, user_display_name_cache)
83
84     if visible?
85       el["lat"] = lat.to_s
86       el["lon"] = lon.to_s
87     end
88
89     add_tags_to_xml_node(el, old_tags)
90
91     el
92   end
93
94   def save_with_dependencies!
95     save!
96
97     tags.each do |k, v|
98       tag = OldNodeTag.new
99       tag.k = k
100       tag.v = v
101       tag.node_id = node_id
102       tag.version = version
103       tag.save!
104     end
105   end
106
107   def tags
108     @tags ||= Hash[old_tags.collect { |t| [t.k, t.v] }]
109   end
110
111   attr_writer :tags
112
113   def tags_as_hash
114     tags
115   end
116
117   # Pretend we're not in any ways
118   def ways
119     []
120   end
121
122   # Pretend we're not in any relations
123   def containing_relation_members
124     []
125   end
126
127   # check whether this element is the latest version - that is,
128   # has the same version as its "current" counterpart.
129   def is_latest_version?
130     current_node.version == version
131   end
132 end