48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/active_tools/active_record/adaptive_belongs_to.rb', line 48
def adaptive_belongs_to(*args)
options = args.
assoc_name = args.first
unless reflection = reflections[assoc_name]
raise(ArgumentError, ":#{assoc_name} method doesn't look like an association accessor!")
end
adapter_name = "#{assoc_name}_adaptive"
raise(TypeError, "Option :attributes must be a Hash. #{options[:attributes].class} passed!") unless options[:attributes].is_a?(Hash)
attr_map = options.delete(:attributes).with_indifferent_access
valid_with assoc_name, :attributes => attr_map
class_attribute :adaptive_options unless defined?(adaptive_options)
self.adaptive_options ||= {}
self.adaptive_options[assoc_name.to_sym] = options.merge(:remote_attributes => attr_map.keys)
class_eval <<-EOV
before_validation do
#{adapter_name}.try_nullify
end
#{Rails.version >= "4.1.0" ? "before_validation" : "before_save"} do
#{adapter_name}.try_commit
end
after_save do
#{adapter_name}.try_destroy_backup
#{adapter_name}.clear!
end
after_destroy do
#{adapter_name}.try_destroy
end
def #{adapter_name}
@#{adapter_name} ||= ActiveTools::ActiveRecord::AdaptiveBelongsTo::Adapter.new(self, :#{assoc_name}, adaptive_options[:#{assoc_name}])
end
EOV
attr_map.each do |remote_attribute, local_attribute|
relation_options_under(local_attribute, assoc_name => remote_attribute)
class_eval do
define_method local_attribute do
send(adapter_name).read(remote_attribute)
end
define_method "#{local_attribute}=" do |value|
send(adapter_name).write(remote_attribute, value)
end
end
end
end
|