anaf_habtm 0.0.82 → 0.0.83

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
 
5
- VERSION = "0.0.82"
5
+ VERSION = "0.0.83"
6
6
 
7
7
  desc 'Default: run unit tests.'
8
8
  task :default => :test
data/anaf_habtm.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{anaf_habtm}
8
- s.version = "0.0.82"
8
+ s.version = "0.0.83"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tyler Gannon"]
12
- s.date = %q{2010-07-11}
12
+ s.date = %q{2010-07-12}
13
13
  s.description = %q{accepts_nested_attributes_for habtm}
14
14
  s.email = %q{t--g__a--nnon@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -21,12 +21,13 @@ Gem::Specification.new do |s|
21
21
  "Rakefile",
22
22
  "anaf_habtm.gemspec",
23
23
  "install.rb",
24
- "lib/anaf_active_record.rb",
25
24
  "lib/anaf_habtm.rb",
26
- "lib/application_helper_methods.rb",
25
+ "lib/anaf_habtm/anaf_active_record.rb",
26
+ "lib/anaf_habtm/application_helper_methods.rb",
27
+ "lib/anaf_habtm/hash.rb",
28
+ "lib/anaf_habtm/string_reader.rb",
27
29
  "lib/generators/anaf_habtm/anaf_habtm_generator.rb",
28
30
  "lib/generators/anaf_habtm/assets/nested_attributes.js",
29
- "lib/hash.rb",
30
31
  "rails/init.rb",
31
32
  "test/anaf_habtm_test.rb",
32
33
  "test/test_helper.rb",
@@ -0,0 +1,159 @@
1
+
2
+ module AnafHabtm
3
+ module ActiveRecord
4
+ # options = {:named=>"name",
5
+ # :ar_options=>{:autosave=>true}}
6
+ def anaf_habtm(association, options={}, &block)
7
+ raise "Must specify :find or a code block." if (block.nil? && !options.has_key?(:find) && !options[:create])
8
+ class_eval do
9
+ # Define a proc that will look up the (potentially) existing object
10
+ finder = proc {|id| association.to_s.singularize.camelize.constantize.where(:id=>id).first
11
+ }
12
+
13
+ # Define a proc that will set the association collection
14
+ set_collection = proc {|me, coll| me.send("#{association.to_s.tableize}=", coll)}
15
+ has_and_belongs_to_many association.to_sym, options[:ar_options]||={}
16
+ # Define the actual association setter.
17
+ define_method "#{association.to_s.tableize}_attributes=", lambda{|attributes_for_association|
18
+ coll = []
19
+ klass = association.to_s.singularize.camelize.constantize
20
+ attributes_for_association.each_value do |params|
21
+ next if params["_destroy"] == "1"
22
+ obj = finder.call(params["id"]) if params.has_key?("id")
23
+ params.extend(AnafHabtm::HashExtension)
24
+ params_copy = params.copy_without_destroy
25
+ # ActiveRecord::Base.attributes=() doesn't like extra parameters.
26
+ if block.nil?
27
+ unless obj
28
+ srch = klass
29
+ options[:find].each do |scope, name|
30
+ if name.class==Hash
31
+ srch = klass.send(scope, params[name.first[0].to_s][name.first[1].to_s])
32
+ else
33
+ srch = klass.send(scope, params[name.to_s])
34
+ end
35
+ obj = srch.first
36
+ end
37
+ obj = obj ||= klass.new if options[:create]
38
+
39
+ unless obj
40
+ raise "Couldn't find or create #{association} named #{name}."
41
+ end
42
+ end
43
+ obj.attributes = params_copy
44
+ obj.save
45
+ coll << obj
46
+ else
47
+ coll << block.call(params_copy, obj)
48
+ end
49
+ end
50
+ set_collection.call(self, coll)
51
+ }
52
+ end
53
+ end
54
+
55
+ def association_text(association, opts={})
56
+ raise "Must give a name for text_association" unless opts.has_key?(:name)
57
+ class_eval do
58
+ if opts.has_key?(:class_name)
59
+ klass = opts[:class_name].constantize
60
+ else
61
+ klass = association.to_s.singularize.camelize.constantize
62
+ end
63
+ define_method "#{association.to_s}_text=", lambda{ |text|
64
+ return if text.empty?
65
+ coll = StringReader.new.read_items(text) do |name, commentary|
66
+ a = klass.undecorate(name) if klass.methods.include?("undecorate")
67
+ if opts.has_key?(:scope)
68
+ obj = self.send(association).scopes[opts[:scope]].call(name).first
69
+ end
70
+ params = {opts[:name]=>name}
71
+ params[opts[:commentary]] = commentary if opts.has_key?(:commentary)
72
+ obj = obj ||= klass.new
73
+ obj = klass.find(obj) unless obj.new_record?
74
+ obj.decoration = a if a
75
+ obj.attributes = params
76
+ obj.save
77
+ obj
78
+ end
79
+ self.send("#{association.to_s}=", coll)
80
+ }
81
+
82
+ define_method "#{association.to_s}_text", lambda{
83
+ StringReader.new.write_items(self.send(association.to_s)) do |item|
84
+ name = item.send(opts[:name])
85
+ name = item.decorate(name) if item.methods.include?("decorate")
86
+ [name, opts.has_key?(:commentary) ? item.send(opts[:commentary]) : ""]
87
+ end
88
+ }
89
+ end
90
+ end
91
+
92
+ def named_association(member, attribute, opts={})
93
+ member = member.to_s
94
+ klass = (opts.has_key?(:class_name) ? opts[:class_name] : member.to_s.singularize.camelize).constantize
95
+ attribute = attribute.to_s
96
+ if opts.has_key?(:create)
97
+ class_eval do
98
+ define_method "#{member}_#{attribute}=", lambda{|value|
99
+ return if value.blank?
100
+ obj = klass.named(value)
101
+ obj = obj ||= klass.create(attribute => value)
102
+ self.send("#{member}=", obj)
103
+ }
104
+ end
105
+ else
106
+ class_eval do
107
+ define_method "#{member}_#{attribute}=", lambda{|value|
108
+ self.send("#{member}=",klass.named(value)) unless value.blank?
109
+ }
110
+ end
111
+ end
112
+ class_eval "def #{member}_#{attribute};
113
+ #{member}.#{attribute} if #{member};
114
+ end;"
115
+ end
116
+
117
+ def search_on(*cols)
118
+ class_eval "def self.search_columns; #{cols.map{|t| t.to_s}.to_ary.inspect}; end;"
119
+ class_eval do
120
+ scope :search, lambda{|str|
121
+ items = like_condition(str.downcase)
122
+ if scopes.has_key?(:search_mod)
123
+ items = items.search_mod
124
+ end
125
+ items
126
+ }
127
+ scope :with_name, lambda{|str|
128
+ equals_condition(str.downcase).limit(1)
129
+ }
130
+ end
131
+ end
132
+
133
+ def lookup(params)
134
+ str = params[:id]
135
+ if str.match(/\D/)
136
+ named(str)
137
+ else
138
+ find(str)
139
+ end
140
+ end
141
+
142
+ def like_condition(str)
143
+ where(condition("ilike '%#{str}%'"))
144
+ end
145
+
146
+ def equals_condition(str)
147
+ where(condition("= '#{str.downcase}'"))
148
+ end
149
+
150
+
151
+ def named(str)
152
+ with_name(str).first
153
+ end
154
+
155
+ def condition(cond)
156
+ search_columns.map{|c| "trim(lower(#{c})) #{cond}"}.join(" or ")
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,113 @@
1
+ module AnafHabtm
2
+ class StringReader
3
+ KEY_SYMPTOM = "*"
4
+ POSS_SYMPTOM = "-"
5
+ START_COMMENT = "{"
6
+ ONE_LINE_COMMENT = "/"
7
+ END_COMMENT = "}"
8
+ NEWLINE = "\n"
9
+
10
+ DELIM = [START_COMMENT, NEWLINE, ONE_LINE_COMMENT, END_COMMENT]
11
+
12
+ MULTI_LINE = :multi_line
13
+ ONE_LINE = :one_line
14
+ NAME = :name
15
+ COMMENT = [MULTI_LINE, ONE_LINE]
16
+
17
+ @item = ""
18
+ @comment = nil
19
+ @items = []
20
+
21
+ def save(block)
22
+ unless @item.strip.empty?
23
+ @items << block.call(@item.strip, @comment.nil? ? nil : @comment.strip)
24
+ end
25
+ @item = ""
26
+ @comment = nil
27
+ end
28
+
29
+ def write_items(coll, &block)
30
+ lines = []
31
+ coll.each do |obj|
32
+ item, comment = block.call(obj)
33
+ if comment.nil? || comment.empty?
34
+ lines << item
35
+ elsif comment.index("/") || comment.index("\n")
36
+ lines << "#{item} {#{comment}}"
37
+ else
38
+ lines << "#{item} / #{comment}"
39
+ end
40
+ end
41
+ lines.join("\n")
42
+ end
43
+
44
+ def read_items(str, &block)
45
+ @items = []
46
+ buffer = ""
47
+ @item = ""
48
+ @comment = nil
49
+ state = NAME
50
+
51
+ str.chars.each do |char|
52
+ if (char == "/") && (state != MULTI_LINE)
53
+ @item = buffer.strip
54
+ buffer = ""
55
+ state = ONE_LINE
56
+ elsif char == "{"
57
+ @item = buffer.strip
58
+ buffer = ""
59
+ state = MULTI_LINE
60
+ elsif char == "}"
61
+ @comment = buffer.strip unless buffer.strip.empty?
62
+ buffer = ""
63
+ save(block)
64
+ state = NAME
65
+ elsif char == "\n"
66
+ if state == NAME
67
+ @item = buffer.strip
68
+ buffer = ""
69
+ save(block)
70
+ elsif state == ONE_LINE
71
+ @comment = buffer.strip
72
+ state = NAME
73
+ buffer = ""
74
+ save(block)
75
+ else
76
+ buffer << char
77
+ end
78
+ else
79
+ buffer << char
80
+ end
81
+ end
82
+
83
+ if state == ONE_LINE
84
+ @comment = buffer
85
+ elsif state == MULTI_LINE
86
+ @comment = buffer
87
+ else
88
+ @item = buffer
89
+ end
90
+ save(block)
91
+ @items
92
+ end
93
+
94
+ def self.parse_symptom(obj, symptom)
95
+ if symptom.index(KEY_SYMPTOM) == 0
96
+ obj.key_symptom = true
97
+ obj.symptom_name = symptom[KEY_SYMPTOM.length..symptom.length]
98
+ elsif symptom.index(POSS_SYMPTOM) == 0
99
+ obj.maybe = true
100
+ obj.symptom_name = symptom[POSS_SYMPTOM.length..symptom.length]
101
+ else
102
+ obj.symptom_name = symptom
103
+ end
104
+ end
105
+
106
+ def self.decorate_symptom(obj)
107
+ decorator = ""
108
+ decorator = KEY_SYMPTOM if obj.key_symptom
109
+ decorator = POSS_SYMPTOM if obj.maybe
110
+ "#{decorator}#{obj.symptom_name}"
111
+ end
112
+ end
113
+ end
data/lib/anaf_habtm.rb CHANGED
@@ -1,6 +1,7 @@
1
- require 'hash'
2
- require 'anaf_active_record'
3
- require 'application_helper_methods'
1
+ require 'anaf_habtm/hash'
2
+ require 'anaf_habtm/anaf_active_record'
3
+ require 'anaf_habtm/application_helper_methods'
4
+ require 'anaf_habtm/string_reader'
4
5
  ActiveRecord::Base.extend(AnafHabtm::ActiveRecord)
5
6
  ActionView::Base.send :include, AnafHabtm::ApplicationHelperMethods
6
7
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anaf_habtm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 187
4
+ hash: 185
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 82
10
- version: 0.0.82
9
+ - 83
10
+ version: 0.0.83
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tyler Gannon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-11 00:00:00 -07:00
18
+ date: 2010-07-12 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -33,12 +33,13 @@ files:
33
33
  - Rakefile
34
34
  - anaf_habtm.gemspec
35
35
  - install.rb
36
- - lib/anaf_active_record.rb
37
36
  - lib/anaf_habtm.rb
38
- - lib/application_helper_methods.rb
37
+ - lib/anaf_habtm/anaf_active_record.rb
38
+ - lib/anaf_habtm/application_helper_methods.rb
39
+ - lib/anaf_habtm/hash.rb
40
+ - lib/anaf_habtm/string_reader.rb
39
41
  - lib/generators/anaf_habtm/anaf_habtm_generator.rb
40
42
  - lib/generators/anaf_habtm/assets/nested_attributes.js
41
- - lib/hash.rb
42
43
  - rails/init.rb
43
44
  - test/anaf_habtm_test.rb
44
45
  - test/test_helper.rb
@@ -1,44 +0,0 @@
1
-
2
- module AnafHabtm
3
- module ActiveRecord
4
- def anaf_habtm(association, options={}, &block)
5
- class_eval do
6
- # Define a proc that will look up the (potentially) existing object
7
- finder = proc {|id| association.to_s.singularize.camelize.constantize.where(:id=>id).first
8
- }
9
-
10
- # Define a proc that will set the association collection
11
- set_collection = proc {|me, coll| me.send("#{association.to_s.tableize}=", coll)}
12
- has_and_belongs_to_many association.to_sym, options
13
- # Define the actual association setter.
14
- define_method "#{association.to_s.tableize}_attributes=", lambda{|attributes_for_association|
15
- coll = []
16
-
17
- attributes_for_association.each_value do |params|
18
- next if params["_destroy"] == "1"
19
- obj = finder.call(params["id"]) if params.has_key?("id")
20
- params.extend(AnafHabtm::HashExtension)
21
- # ActiveRecord::Base.attributes=() doesn't like extra parameters.
22
- coll << block.call(params.copy_without_destroy, obj)
23
- end
24
- set_collection.call(self, coll)
25
- }
26
- end
27
- end
28
-
29
- def named_association(member, attribute, opts={})
30
- member = member.to_s
31
- klass = opts.has_key?(:class) ? opts[:class_name] : member.to_s.singularize.camelize
32
- attribute = attribute.to_s
33
- if opts.has_key?(:create)
34
- class_eval "def #{member}_#{attribute}=(#{attribute});
35
- return if #{attribute}.blank?
36
- self.#{member} = #{klass}.find_or_create_by_#{attribute}(#{attribute})
37
- end;"
38
- else
39
- class_eval "def #{member}_#{attribute}=(#{attribute}); self.#{member} = #{klass}.find_by_#{attribute}(#{attribute}) unless #{attribute}.blank?; end;"
40
- end
41
- class_eval "def #{member}_#{attribute}; #{member}.#{attribute} if #{member}; end;"
42
- end
43
- end
44
- end
File without changes