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 <<-EOV
define_method "find_#{singular_association}_value" do |name|
(opt = #{association_name}.find_by_name(name.to_s)) ? opt.value : nil
end
define_method "find_#{singular_association}_values" do |name|
#{association_name}.find_all_by_name(name.to_s).collect(&:value)
end
define_method "#{association_name}_hash" do
option_hash = Hash.new {|h,k| h[k] = []}
#{association_name}.each do |option|
option_hash[option.name] << option.value.to_s
end
option_hash
end
define_method "#{association_name}_hash_interned" do
result = #{association_name}_hash
result.symbolize_keys!
result.each_pair do |k,v|
result[k] = nil if v.length == 0
result[k] = v.first if v.length == 1
end
end
define_method "set_#{singular_association}!" do |name, *values|
name = name.to_s
existing = #{association_name}.find_all_by_name(name)
new_opts = []
values.each do |value|
if (match = existing.detect { |opt| opt.value == value})
existing.delete(match)
new_opts <<match
else
new_opts << #{association_name}.create!(:name => name, :value => value)
end
end
existing.each { |opt| opt.destroy }
return new_opts
end
EOV
end
|