25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
|
# File 'lib/polymorpheus/interface.rb', line 25
def belongs_to_polymorphic(*args)
options = args.
polymorphic_api = options[:as]
associations = args.collect(&:to_s).collect(&:downcase)
association_keys = associations.collect{|association| "#{association}_id"}
associations.each do |associated_model|
belongs_to associated_model.to_sym
end
const_set "#{polymorphic_api}_keys".upcase, association_keys
define_method "#{polymorphic_api}_types" do
associations
end
define_method "#{polymorphic_api}_active_key" do
keys = association_keys.select { |key| self.send(key).present? }
keys.first if keys.length == 1
end
define_method "#{polymorphic_api}_query_condition" do
fk = self.send("#{polymorphic_api}_active_key")
{ fk.to_s => self.send(fk) } if fk
end
define_method polymorphic_api do
if key = self.send("#{polymorphic_api}_active_key")
self.send key.gsub(/_id$/,'')
else
objs = associations.map { |association| self.send(association) }.compact
objs.first if objs.length == 1
end
end
define_method "#{polymorphic_api}=" do |polymorphic_obj|
klass_ancestors = polymorphic_obj.class
.ancestors.map(&:name).compact.map(&:underscore)
match = associations & klass_ancestors
if match.blank?
raise Polymorpheus::Interface::InvalidTypeError, associations
elsif match.length > 1
raise Polymorpheus::Interface::AmbiguousTypeError
else
accessor = "#{polymorphic_obj.class.base_class.name.underscore}_id="
self.send(accessor, polymorphic_obj.id)
(associations - match).each do |association_to_reset|
self.send("#{association_to_reset}_id=", nil)
end
end
end
define_method "polymorphic_#{polymorphic_api}_relationship_is_valid" do
if !self.send(polymorphic_api)
self.errors.add(:base,
"You must specify exactly one of the following: {#{associations.join(', ')}}")
end
end
private "polymorphic_#{polymorphic_api}_relationship_is_valid"
end
|