lib/cistern/associations.rb in cistern-2.7.0 vs lib/cistern/associations.rb in cistern-2.7.1

- old
+ new

@@ -1,8 +1,18 @@ # frozen_string_literal: true module Cistern::Associations + def self.extended(klass) + def klass.association_overlay + @association_overlay ||= const_set(:Associations, Module.new) + end + + klass.send(:include, klass.association_overlay) + + super + end + # Lists the associations defined on the resource # @return [Hash{Symbol=>Array}] mapping of association type to name def associations @associations ||= Hash.new { |h,k| h[k] = [] } end @@ -15,29 +25,36 @@ # @example # class Firm < Law::Model # identity :registration_id # has_many :lawyers, -> { cistern.associates(firm_id: identity) } # end - def has_many(name, scope) + def has_many(name, *args, &block) name_sym = name.to_sym reader_method = name writer_method = "#{name}=" - attribute name, type: :array + options = args.last.is_a?(::Hash) ? args.pop : {} + scope = args.first || block - define_method reader_method do - collection = instance_exec(&scope) - records = attributes[name_sym] || [] + attribute name_sym, options.merge(writer: false, reader: false, type: :array) - collection.load(records) if records.any? - collection + association_overlay.module_eval do + define_method reader_method do + collection = instance_exec(&scope) + records = attributes[name_sym] || [] + + collection.load(records) if records.any? + collection + end end - define_method writer_method do |models| - attributes[name] = Array(models).map do |model| - model.respond_to?(:attributes) ? model.attributes : model + association_overlay.module_eval do + define_method writer_method do |models| + attributes[name] = Array(models).map do |model| + model.respond_to?(:attributes) ? model.attributes : model + end end end associations[:has_many] << name_sym end @@ -49,27 +66,34 @@ # @example # class Firm < Law::Model # identity :registration_id # belongs_to :leader, -> { cistern.employees.get(:ceo) } # end - def belongs_to(name, block) + def belongs_to(name, *args, &block) name_sym = name.to_sym reader_method = name writer_method = "#{name}=" - attribute name_sym + options = args.last.is_a?(::Hash) ? args.pop : {} + scope = args.first || block - define_method reader_method do - model = instance_exec(&block) - attributes[name_sym] = model.attributes - model + attribute name_sym, options.merge(writer: false, reader: false) + + association_overlay.module_eval do + define_method reader_method do + model = instance_exec(&scope) + attributes[name_sym] = model.attributes + model + end end - define_method writer_method do |model| - data = model.respond_to?(:attributes) ? model.attributes : model - attributes[name_sym] = data - model + association_overlay.module_eval do + define_method writer_method do |model| + data = model.respond_to?(:attributes) ? model.attributes : model + attributes[name_sym] = data + model + end end associations[:belongs_to] << name_sym end end