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
101
102
|
# File 'lib/active_record/json_associations.rb', line 50
def has_many many, scope = nil, options = {}, &extension
unless (scope.is_a?(Hash) && scope[:json_foreign_key]) || (options.is_a?(Hash) && options[:json_foreign_key])
return super
end
if scope.is_a?(Hash)
options = scope
scope = nil
end
one = many.to_s.singularize
one_ids = :"#{one}_ids"
one_ids_equals = :"#{one_ids}="
many_equals = :"#{many}="
many_eh = :"#{many}?"
class_name = options[:class_name] || one.classify
foreign_key = options[:json_foreign_key]
foreign_key = :"#{model_name.singular}_ids" if foreign_key == true
include Module.new {
define_method one_ids do
send(many).pluck(:id)
end
define_method one_ids_equals do |ids|
klass = class_name.constantize
normalized_ids = Array(ids).select(&:present?).map(&:to_i)
send many_equals, klass.find(normalized_ids)
end
define_method many do
klass = class_name.constantize
klass.where("#{foreign_key} LIKE '[#{id}]'").or(
klass.where("#{foreign_key} LIKE '[#{id},%'")).or(
klass.where("#{foreign_key} LIKE '%,#{id},%'")).or(
klass.where("#{foreign_key} LIKE '%,#{id}]'"))
end
define_method many_equals do |collection|
collection.each do |record|
new_id_array = Array(record.send(foreign_key)) | [id]
raise "FIXME: Cannot assign during creation, because no id has yet been reified." if new_id_array.any?(&:nil?)
record.update foreign_key => new_id_array
end
end
define_method many_eh do
send(many).any?
end
}
end
|