diff options
| author | Zog | 2018-04-03 08:51:32 +0200 |
|---|---|---|
| committer | Zog | 2018-04-09 16:58:24 +0200 |
| commit | af7ec988e86f8927ac6493acd5874607b7e167d8 (patch) | |
| tree | 7d0f04f0dea2a8a913aec17ed285acaad6aac43f | |
| parent | bf745bf731237f4d405065de5d386eaee2a2d131 (diff) | |
| download | chouette-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.rb | 35 | ||||
| -rw-r--r-- | app/models/merge.rb | 16 | ||||
| -rw-r--r-- | spec/models/route_spec.rb | 42 |
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 |
