diff options
| author | Zog | 2018-03-30 14:46:37 +0200 |
|---|---|---|
| committer | Zog | 2018-04-09 16:57:59 +0200 |
| commit | 745428deb8e0df2c7c8a991ab8a5f5231e6d6c7f (patch) | |
| tree | 40da9487591cef17947da0c2a23d05b5e06bd1bb | |
| parent | 98c723ee956b478e8ffb466e461c9889a272efdf (diff) | |
| download | chouette-core-745428deb8e0df2c7c8a991ab8a5f5231e6d6c7f.tar.bz2 | |
Refs #6367; Add metadata to routes
| -rw-r--r-- | app/controllers/application_controller.rb | 2 | ||||
| -rw-r--r-- | app/controllers/concerns/metadata_controller_support.rb | 21 | ||||
| -rw-r--r-- | app/helpers/application_helper.rb | 2 | ||||
| -rw-r--r-- | app/models/chouette/active_record.rb | 2 | ||||
| -rw-r--r-- | app/models/chouette/route.rb | 4 | ||||
| -rw-r--r-- | app/models/concerns/metadata_support.rb | 74 | ||||
| -rw-r--r-- | db/migrate/20180330074336_add_metadata_to_routes.rb | 5 | ||||
| -rw-r--r-- | spec/models/chouette/route/route_base_spec.rb | 3 | ||||
| -rw-r--r-- | spec/models/route_spec.rb | 26 |
9 files changed, 133 insertions, 6 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9a83394e2..4a89410d3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ class ApplicationController < ActionController::Base include PaperTrailSupport + include MetadataControllerSupport include Pundit include FeatureChecker @@ -10,7 +11,6 @@ class ApplicationController < ActionController::Base before_action :authenticate_user! before_action :set_locale - # Load helpers in rails engine helper LanguageEngine::Engine.helpers diff --git a/app/controllers/concerns/metadata_controller_support.rb b/app/controllers/concerns/metadata_controller_support.rb new file mode 100644 index 000000000..4ac625c01 --- /dev/null +++ b/app/controllers/concerns/metadata_controller_support.rb @@ -0,0 +1,21 @@ +module MetadataControllerSupport + extend ActiveSupport::Concern + + included do + after_action :set_creator_metadata, only: :create + after_action :set_modifier_metadata, only: :update + end + + def user_for_metadata + current_user ? current_user.username : '' + end + + def set_creator_metadata + resource.try(:set_metadata!, :creator_username, user_for_metadata) if resource.valid? + end + + def set_modifier_metadata + resource.try :set_metadata!, :modifier_username, user_for_metadata + end + +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a0c6796ea..63398a0a9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -14,7 +14,7 @@ module ApplicationHelper def page_header_title(object) # Unwrap from decorator, we want to know the object model name object = object.object if object.try(:object) - + if Referential === object return object.full_name end diff --git a/app/models/chouette/active_record.rb b/app/models/chouette/active_record.rb index c2aab9d50..b010384ea 100644 --- a/app/models/chouette/active_record.rb +++ b/app/models/chouette/active_record.rb @@ -2,6 +2,8 @@ require 'deep_cloneable' module Chouette class ActiveRecord < ::ActiveRecord::Base + include MetadataSupport + self.abstract_class = true before_save :nil_if_blank, :set_data_source_ref diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 65947c392..9c7a3e6d9 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -1,6 +1,7 @@ module Chouette class Route < Chouette::TridentActiveRecord - has_paper_trail + has_metadata + include RouteRestrictions include ChecksumSupport include ObjectidSupport @@ -9,7 +10,6 @@ module Chouette enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east) enumerize :wayback, in: %i(outbound inbound), default: :outbound - def self.nullable_attributes [:published_name, :comment, :number, :name, :direction, :wayback] end diff --git a/app/models/concerns/metadata_support.rb b/app/models/concerns/metadata_support.rb new file mode 100644 index 000000000..a1daf6b2e --- /dev/null +++ b/app/models/concerns/metadata_support.rb @@ -0,0 +1,74 @@ +module MetadataSupport + extend ActiveSupport::Concern + + included do + class << self + def has_metadata? + !!@has_metadata + end + + def has_metadata opts={} + @has_metadata = true + + define_method :metadata do + attr_name = opts[:attr_name] || :metadata + @wrapped_metadata ||= begin + wrapped = MetadataSupport::MetadataWrapper.new self.read_attribute(attr_name) + wrapped.attribute_name = attr_name + wrapped.owner = self + wrapped + end + end + + define_method :set_metadata! do |name, value| + self.metadata.send "#{name}=", value + self.save! + end + end + end + end + + def has_metadata? + self.class.has_metadata? + end + + class MetadataWrapper < OpenStruct + attr_accessor :attribute_name, :owner + + def is_timestamp_attr? name + name =~ /_updated_at$/ + end + + def method_missing(mid, *args) + out = super(mid, *args) + owner.write_attribute attribute_name, @table + out = out&.to_time if args.length == 0 && is_timestamp_attr?(mid) + out + end + + def new_ostruct_member name + unless is_timestamp_attr?(name) + timestamp_attr_name = "#{name}_updated_at".to_sym + end + + name = name.to_sym + unless respond_to?(name) + if timestamp_attr_name + define_singleton_method(timestamp_attr_name) { @table[timestamp_attr_name]&.to_time } + define_singleton_method(name) { @table[name] } + else + # we are defining an accessor for a timestamp + define_singleton_method(name) { @table[name]&.to_time } + end + + define_singleton_method("#{name}=") do |x| + modifiable[timestamp_attr_name] = Time.now if timestamp_attr_name + modifiable[name] = x + owner.write_attribute attribute_name, @table + end + modifiable[timestamp_attr_name] = Time.now if timestamp_attr_name + end + name + end + end +end diff --git a/db/migrate/20180330074336_add_metadata_to_routes.rb b/db/migrate/20180330074336_add_metadata_to_routes.rb new file mode 100644 index 000000000..8d4ccf63d --- /dev/null +++ b/db/migrate/20180330074336_add_metadata_to_routes.rb @@ -0,0 +1,5 @@ +class AddMetadataToRoutes < ActiveRecord::Migration + def change + add_column :routes, :metadata, :json + end +end diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb index d24ad6348..3d4a87791 100644 --- a/spec/models/chouette/route/route_base_spec.rb +++ b/spec/models/chouette/route/route_base_spec.rb @@ -15,8 +15,7 @@ RSpec.describe Chouette::Route, :type => :model do #it { is_expected.to validate_presence_of :direction_code } it { is_expected.to validate_inclusion_of(:direction).in_array(%i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)) } it { is_expected.to validate_inclusion_of(:wayback).in_array(%i(outbound inbound)) } - it { is_expected.to be_versioned } - + context "reordering methods" do let(:bad_stop_point_ids){subject.stop_points.map { |sp| sp.id + 1}} let(:ident){subject.stop_points.map(&:id)} diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb new file mode 100644 index 000000000..a101e62d9 --- /dev/null +++ b/spec/models/route_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +RSpec.describe Chouette::Route, :type => :model do + subject(:route){ create :route } + context "metadatas" do + it "should be empty at first" do + expect(Chouette::Route.has_metadata?).to be_truthy + expect(route.has_metadata?).to be_truthy + expect(route.metadata.creator_username).to be_nil + expect(route.metadata.modifier_username).to be_nil + end + + context "once set" do + it "should set the correct values" do + Timecop.freeze(Time.now) do + route.metadata.creator_username = "john.doe" + route.save! + id = route.id + route = Chouette::Route.find id + expect(route.metadata.creator_username).to eq "john.doe" + expect(route.metadata.creator_username_updated_at.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N') + end + end + end + end +end |
