9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
|
# File 'lib/source_ids.rb', line 9
def accepts_source_ids_for(source_association_name, options = {})
source_association = reflect_on_association(source_association_name)
raise "Could not find association #{source_association_name}" unless source_association
relation = source_association.through_reflection
raise "#{source_association_name} does not have :through" unless relation
fk_in_relation = source_association.source_reflection.foreign_key
source_ids_name = options[:as] || "#{source_association_name.to_s.singularize}_ids"
define_method "_#{source_ids_name}=" do |ids|
ids = ids.find_all(&:present?)
send(relation.name).each do |r|
source_id = r.send(fk_in_relation)
r.mark_for_destruction unless ids.include?(source_id)
end
ids.each do |source_id|
unless send(relation.name).detect{|r| r.send(fk_in_relation) == source_id}
send(relation.name).build(fk_in_relation => source_id)
end
end
send(relation.name).target.sort do |a, b|
if a.marked_for_destruction? && b.marked_for_destruction?
0
elsif a.marked_for_destruction?
-1
elsif b.marked_for_destruction?
1
else
ids.index(a.send(fk_in_relation)) <=> ids.index(b.send(fk_in_relation))
end
end
end
define_method "_#{source_ids_name}" do
send(relation.name).find_all{|r| !r.marked_for_destruction?}.map(&fk_in_relation.to_sym)
end
end
|