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 | 
