aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZog2018-04-03 08:51:32 +0200
committerZog2018-04-09 16:58:24 +0200
commitaf7ec988e86f8927ac6493acd5874607b7e167d8 (patch)
tree7d0f04f0dea2a8a913aec17ed285acaad6aac43f
parentbf745bf731237f4d405065de5d386eaee2a2d131 (diff)
downloadchouette-core-af7ec988e86f8927ac6493acd5874607b7e167d8.tar.bz2
Refs #6367; Add a merge mechanism
And use it in the Referential merge operation
-rw-r--r--app/models/concerns/metadata_support.rb35
-rw-r--r--app/models/merge.rb16
-rw-r--r--spec/models/route_spec.rb42
3 files changed, 88 insertions, 5 deletions
diff --git a/app/models/concerns/metadata_support.rb b/app/models/concerns/metadata_support.rb
index 0075d9391..c4bedbcda 100644
--- a/app/models/concerns/metadata_support.rb
+++ b/app/models/concerns/metadata_support.rb
@@ -20,6 +20,11 @@ module MetadataSupport
end
end
+ define_method :metadata= do |val|
+ @wrapped_metadata = nil
+ super val
+ end
+
define_method :set_metadata! do |name, value|
self.metadata.send "#{name}=", value
self.save!
@@ -32,6 +37,24 @@ module MetadataSupport
self.class.has_metadata?
end
+ def merge_metadata_from source
+ return unless source.has_metadata?
+ source_metadata = source.metadata
+ res = {}
+ self.metadata.each do |k, v|
+ unless self.metadata.is_timestamp_attr?(k)
+ ts = self.metadata.timestamp_attr(k)
+ if source_metadata[ts] && source_metadata[ts] > self.metadata[ts]
+ res[k] = source_metadata[k]
+ else
+ res[k] = v
+ end
+ end
+ end
+ self.metadata = res
+ self
+ end
+
class MetadataWrapper < OpenStruct
attr_accessor :attribute_name, :owner
@@ -39,6 +62,10 @@ module MetadataSupport
name =~ /_updated_at$/
end
+ def timestamp_attr name
+ "#{name}_updated_at".to_sym
+ end
+
def method_missing(mid, *args)
out = super(mid, *args)
owner.send :write_attribute, attribute_name, @table
@@ -46,9 +73,15 @@ module MetadataSupport
out
end
+ def each
+ @table.each do |k,v|
+ yield k, v
+ end
+ end
+
def new_ostruct_member name
unless is_timestamp_attr?(name)
- timestamp_attr_name = "#{name}_updated_at".to_sym
+ timestamp_attr_name = timestamp_attr(name)
end
name = name.to_sym
diff --git a/app/models/merge.rb b/app/models/merge.rb
index 8038b5f0f..6e2a7036a 100644
--- a/app/models/merge.rb
+++ b/app/models/merge.rb
@@ -138,7 +138,9 @@ class Merge < ApplicationModel
new.switch do
referential_routes.each do |route|
existing_route = new.routes.find_by line_id: route.line_id, checksum: route.checksum
- unless existing_route
+ if existing_route
+ existing_route.merge_metadata_from route
+ else
objectid = Chouette::Route.where(objectid: route.objectid).exists? ? nil : route.objectid
attributes = route.attributes.merge(
id: nil,
@@ -196,7 +198,9 @@ class Merge < ApplicationModel
existing_journey_pattern = new.journey_patterns.find_by route_id: existing_associated_route.id, checksum: journey_pattern.checksum
- unless existing_journey_pattern
+ if existing_journey_pattern
+ existing_journey_pattern.merge_metadata_from journey_pattern
+ else
objectid = Chouette::JourneyPattern.where(objectid: journey_pattern.objectid).exists? ? nil : journey_pattern.objectid
attributes = journey_pattern.attributes.merge(
id: nil,
@@ -241,7 +245,9 @@ class Merge < ApplicationModel
existing_vehicle_journey = new.vehicle_journeys.find_by journey_pattern_id: existing_associated_journey_pattern.id, checksum: vehicle_journey.checksum
- unless existing_vehicle_journey
+ if existing_vehicle_journey
+ existing_vehicle_journey.merge_metadata_from vehicle_journey
+ else
objectid = Chouette::VehicleJourney.where(objectid: vehicle_journey.objectid).exists? ? nil : vehicle_journey.objectid
attributes = vehicle_journey.attributes.merge(
id: nil,
@@ -338,7 +344,9 @@ class Merge < ApplicationModel
existing_time_table = line.time_tables.find_by checksum: candidate_time_table.checksum
- unless existing_time_table
+ if existing_time_table
+ existing_time_table.merge_metadata_from candidate_time_table
+ else
objectid = Chouette::TimeTable.where(objectid: time_table.objectid).exists? ? nil : time_table.objectid
candidate_time_table.objectid = objectid
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
index a101e62d9..b407cd866 100644
--- a/spec/models/route_spec.rb
+++ b/spec/models/route_spec.rb
@@ -22,5 +22,47 @@ RSpec.describe Chouette::Route, :type => :model do
end
end
end
+
+ describe "#merge_metadata_from" do
+ let(:source){ create :route }
+ let(:metadata){ target.merge_metadata_from(source).metadata }
+ let(:target){ create :route }
+ before do
+ target.metadata.creator_username = "john"
+ target.metadata.modifier_username = "john"
+ end
+ context "when the source has no metadata" do
+ it "should do nothing" do
+ expect(metadata.creator_username).to eq "john"
+ expect(metadata.modifier_username).to eq "john"
+ end
+ end
+
+ context "when the source has older metadata" do
+ before do
+ source.metadata.creator_username = "jane"
+ source.metadata.modifier_username = "jane"
+ source.metadata.creator_username_updated_at = 1.month.ago
+ source.metadata.modifier_username_updated_at = 1.month.ago
+ end
+ it "should do nothing" do
+ expect(metadata.creator_username).to eq "john"
+ expect(metadata.modifier_username).to eq "john"
+ end
+ end
+
+ context "when the source has new metadata" do
+ before do
+ source.metadata.creator_username = "jane"
+ source.metadata.modifier_username = "jane"
+ target.metadata.creator_username_updated_at = 1.month.ago
+ target.metadata.modifier_username_updated_at = 1.month.ago
+ end
+ it "should update metadata" do
+ expect(metadata.creator_username).to eq "jane"
+ expect(metadata.modifier_username).to eq "jane"
+ end
+ end
+ end
end
end