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