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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# File 'lib/has_options/has_options.rb', line 12
def has_options(options={})
configuration = { :option_model => "Option", :association_name => :options}
configuration.update(options) if options.is_a?(Hash)
association_name = configuration[:association_name].to_s
singular_association = association_name.singularize
option_model = configuration[:option_model]
table_name = option_model.constantize.table_name
has_many association_name, :class_name => configuration[:option_model], :as => :entity, :dependent => :destroy, :conditions => {:association_type => association_name}
accepts_nested_attributes_for association_name, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
class_eval " define_method \"find_\#{singular_association}_value\" do |name|\n (opt = \#{association_name}.find_by_name(name.to_s)) ? opt.value : nil \n end\n\n define_method \"find_\#{singular_association}_values\" do |name|\n \#{association_name}.find_all_by_name(name.to_s).collect(&:value)\n end\n\n define_method \"\#{association_name}_hash\" do\n option_hash = Hash.new {|h,k| h[k] = []}\n\n \#{association_name}.each do |option|\n option_hash[option.name] << option.value.to_s\n end\n\n option_hash\n end\n\n define_method \"\#{association_name}_hash_interned\" do\n result = \#{association_name}_hash\n result.symbolize_keys!\n \n result.each_pair do |k,v|\n result[k] = nil if v.length == 0\n result[k] = v.first if v.length == 1\n end\n end\n \n define_method \"set_\#{singular_association}!\" do |name, *values|\n name = name.to_s\n existing = \#{association_name}.find_all_by_name(name)\n new_opts = []\n values.each do |value|\n if (match = existing.detect { |opt| opt.value == value})\n existing.delete(match)\n new_opts <<match\n else\n new_opts << \#{association_name}.create!(:name => name, :value => value)\n end\n end\n \n existing.each { |opt| opt.destroy }\n \n return new_opts\n end\n EOV\n\nend\n"
|