@@ -9,16 +9,12 @@ module VirtualAttributes
99 module VirtualDelegates
1010 extend ActiveSupport ::Concern
1111
12- included do
13- class_attribute :virtual_delegates_to_define , :instance_accessor => false , :default => { }
14- end
15-
1612 module ClassMethods
1713 #
1814 # Definition
1915 #
2016
21- def virtual_delegate ( *methods , to :, type :, prefix : nil , allow_nil : nil , default : nil , **options ) # rubocop:disable Naming/MethodParameterName
17+ def virtual_delegate ( *methods , to :, type :, prefix : nil , allow_nil : nil , default : nil , uses : nil , **options ) # rubocop:disable Naming/MethodParameterName
2218 to = to . to_s
2319 if to . include? ( "." ) && ( methods . size > 1 || prefix )
2420 raise ArgumentError , 'Delegation only supports specifying a target method name when defining a single virtual method with no prefix'
@@ -32,38 +28,17 @@ def virtual_delegate(*methods, to:, type:, prefix: nil, allow_nil: nil, default:
3228 # This better supports reloading of the class and changing the definitions
3329 methods . each do |method |
3430 method_name , to , method = determine_method_names ( method , to , prefix )
35- define_delegate ( method_name , method , :to => to , :allow_nil => allow_nil , :default => default )
31+ unless ( to_ref = reflection_with_virtual ( to ) )
32+ raise ArgumentError , "Delegation needs an association. Association #{ to } does not exist"
33+ end
3634
37- self . virtual_delegates_to_define =
38- virtual_delegates_to_define . merge ( method_name . to_s => [ method , options . merge ( :to => to , :type => type ) ] )
35+ define_delegate ( method_name , method , :to => to , :allow_nil => allow_nil , :default => default )
36+ virtual_attribute ( method_name , type , :uses => ( uses || to ) , :arel => virtual_delegate_arel ( method , to_ref ) , ** options )
3937 end
4038 end
4139
4240 private
4341
44- # define virtual_attribute for delegates
45- #
46- # this is called at schema load time (and not at class definition time)
47- #
48- # @param method_name [Symbol] name of the attribute on the source class to be defined
49- # @param col [Symbol] name of the attribute on the associated class to be referenced
50- # @option options :to [Symbol] name of the association from the source class to be referenced
51- # @option options :arel [Proc] (optional and not common)
52- # @option options :uses [Array|Symbol|Hash] sql includes hash. (default: to)
53- # @option options :type [Symbol|ActiveModel::Type::Value] type for the attribute
54- def define_virtual_delegate ( method_name , col , options )
55- unless ( to = options [ :to ] ) && ( to_ref = reflection_with_virtual ( to . to_s ) )
56- raise ArgumentError , 'Delegation needs an association. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
57- end
58-
59- col = col . to_s
60- type = options [ :type ]
61- type = ActiveRecord ::Type . lookup ( type ) if type . kind_of? ( Symbol )
62-
63- arel = virtual_delegate_arel ( col , to_ref )
64- define_virtual_attribute ( method_name , type , :uses => ( options [ :uses ] || to ) , :arel => arel )
65- end
66-
6742 # see activesupport module/delegation.rb
6843 # rubocop:disable Style/TernaryParentheses
6944 def define_delegate ( method_name , method , to : nil , allow_nil : nil , default : nil ) # rubocop:disable Naming/MethodParameterName
0 commit comments