lib/terrestrial/relation_mapping.rb in terrestrial-0.3.0 vs lib/terrestrial/relation_mapping.rb in terrestrial-0.5.0

- old
+ new

@@ -1,40 +1,52 @@ require "terrestrial/error" -require "terrestrial/upserted_record" +require "terrestrial/upsert_record" require "terrestrial/deleted_record" module Terrestrial class RelationMapping - def initialize(name:, namespace:, fields:, primary_key:, factory:, serializer:, associations:, subsets:) + def initialize(name:, namespace:, fields:, database_owned_fields:, database_default_fields:, primary_key:, factory:, serializer:, associations:, subsets:, observers:) @name = name @namespace = namespace @fields = fields + @database_owned_fields = database_owned_fields + @database_default_fields = database_default_fields @primary_key = primary_key @factory = factory @serializer = serializer @associations = associations @subsets = subsets + @observers = observers + + @incoming_foreign_keys = [] end - attr_reader :name, :namespace, :fields, :primary_key, :factory, :serializer, :associations, :subsets - private :factory, :serializer + attr_reader :name, :namespace, :fields, :database_owned_fields, :database_default_fields, :primary_key, :factory, :serializer, :associations, :subsets, :created_at_field, :updated_at_field, :observers + private :factory, :serializer, :observers def add_association(name, new_association) @associations = associations.merge(name => new_association) end + def register_foreign_key(fk) + @incoming_foreign_keys += fk + end + def load(record) - factory.call(record) + factory.call(reject_non_factory_fields(record)) rescue => e raise LoadError.new(namespace, factory, record, e) end def serialize(object, depth, foreign_keys = {}) object_attributes = serializer.call(object) + record = upsertable_record(object, object_attributes, depth, foreign_keys) + observers.each { |o| o.post_serialize(self, object, record) } + [ - record(object_attributes, depth, foreign_keys), + record, extract_associations(object_attributes) ] rescue => e raise SerializationError.new(name, serializer, object, e) end @@ -43,25 +55,32 @@ object_attributes = serializer.call(object) [deleted_record(object_attributes, depth)] end + def post_save(object, record, new_attributes) + new_record = upsertable_record(object, new_attributes, 0, {}) + + observers.each { |o| o.post_save(self, object, record, new_record) } + + record.merge!(new_attributes) + end + private - def record(attributes, depth, foreign_keys) - UpsertedRecord.new( - namespace, - primary_key, + def upsertable_record(object, attributes, depth, foreign_keys) + UpsertRecord.new( + self, + object, select_mapped_fields(attributes).merge(foreign_keys), depth, ) end def deleted_record(attributes, depth) DeletedRecord.new( - namespace, - primary_key, + self, attributes, depth, ) end @@ -73,8 +92,20 @@ ] end def select_mapped_fields(attributes) attributes.select { |name, _value| fields.include?(name) } + end + + def reject_non_factory_fields(attributes) + attributes.reject { |name, _value| (@incoming_foreign_keys + local_foreign_keys).include?(name) } + end + + def factory_fields + @factory_fields ||= fields - (local_foreign_keys + @incoming_foreign_keys) + end + + def local_foreign_keys + @local_foreign_keys ||= associations.values.flat_map(&:local_foreign_keys) end end end