acts_as_itemized 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/acts_as_itemized.rb +74 -80
  2. metadata +1 -1
@@ -11,7 +11,7 @@ module ActsAsItemized
11
11
 
12
12
  after_save :commit_item_changes
13
13
 
14
- has_many :itemized_items, :order => "position" do
14
+ has_many :itemized_items, :as => :itemizable, :order => :position do
15
15
  def where_type(conditions)
16
16
  conditions = (conditions.is_a? Array) ? conditions.collect(&:to_s) : conditions.to_s
17
17
  scoped(:conditions => {:item_type => conditions } )
@@ -26,14 +26,7 @@ module ActsAsItemized
26
26
  def contents
27
27
  all.collect(&:content)
28
28
  end
29
- def to_h
30
- all.inject({}) do |result, item|
31
- key = item.item_type
32
- result[key] = ( result[key] || {} ).merge(item.to_h)
33
- result
34
- end
35
- end
36
-
29
+
37
30
  end
38
31
 
39
32
  end
@@ -41,43 +34,24 @@ module ActsAsItemized
41
34
  end
42
35
 
43
36
  module SingletonMethods
44
- def items(type = false)
45
- sql = (sql || "") + "itemized_items.item_type = ? AND " if type
46
- sql = (sql || "") + "itemized_items.parent_id IN (?) "
47
- conditions = [sql]
48
- conditions << type.to_s if type
49
- conditions << all
37
+ def itemized_items(type = false)
38
+ conditions = {}
39
+ conditions[:itemized_items] = {:item_type => type} unless type.blank?
40
+ conditions[:itemized_items] = {:itemizable_id => all, :itemizable_type => self.name} unless all.blank?
50
41
  ItemizedItem.scoped(:conditions => conditions)
51
42
  end
52
43
  end
53
44
 
54
45
  module InstanceMethods
55
46
 
56
- def items
57
- itemized_items
58
- end
59
-
60
- def item_options
61
- @item_options ||= {}
47
+ def itemized_options
48
+ @itemized_options ||= {}
62
49
  end
63
- def item_options_with_sorting
64
- item_options.sort_by{|k,io| io[:position] || 0}
50
+ def itemized_options_with_sorting
51
+ itemized_options.sort_by{|k,io| io[:position] || 0}
65
52
  end
66
-
67
- # Load items into @attributes from self.itemized_items
68
- def eager_load_items
69
- item_options.each do |type_many, options|
70
- type_one = type_many.to_s.singularize
71
- item_options[type_many][:count].times do |id|
72
- position = id + 1
73
- options[:columns].each do |column|
74
- self.send("#{type_one}_#{column}_#{position}")
75
- end
76
- end
77
- end
78
- self.attributes
79
- end
80
-
53
+
54
+
81
55
  # ITEM CHANGES
82
56
 
83
57
  def item_changes
@@ -102,16 +76,16 @@ module ActsAsItemized
102
76
  protected
103
77
 
104
78
  # ITEM CHANGES
105
- def add_items(*args)
79
+ def itemize(*args)
106
80
  args.each do |arg|
107
- next if item_options.has_key?(arg.is_a?(Hash) ? arg.keys.first : arg)
108
- options = item_options_with_defaults(arg)
109
- @item_options.merge!(options)
81
+ next if itemized_options.has_key?(arg.is_a?(Hash) ? arg.keys.first : arg)
82
+ options = itemized_options_with_defaults(arg)
83
+ @itemized_options.merge!(options)
110
84
  create_item_accessors(options)
111
85
  end
112
86
  end
113
87
 
114
- def item_options_with_defaults(arg)
88
+ def itemized_options_with_defaults(arg)
115
89
  key = arg.is_a?(Hash) ? arg.keys.first : arg.to_sym
116
90
  options = arg.is_a?(Hash) ? arg[key] : {}
117
91
  options = {
@@ -125,7 +99,7 @@ module ActsAsItemized
125
99
  options[:tabindex_score] = tabindex_with_auto_increment(options[:count], options[:tabindex_score][0], options[:tabindex_score][1], options[:tabindex_score][2]) if options[:tabindex_score]
126
100
  return {key => options}
127
101
  end
128
-
102
+
129
103
  def set_item_change(changes)
130
104
  changes.each do |key, value|
131
105
  next if attributes[key] == value
@@ -188,41 +162,62 @@ module ActsAsItemized
188
162
 
189
163
  # ITEM CRUD
190
164
 
191
- def create_item_accessors(_item_options)
192
- _item_options.each do |type_many, options|
193
- # singular item
194
- type_one = type_many.to_s.singularize
195
- # total
196
- count = _item_options[type_many][:count]
197
- # access all of type
198
- class_eval <<-END, __FILE__, (__LINE__+1)
199
- def #{type_many}
200
- @#{type_many} ||= #{count}.times.inject([]){|r,position| r << self.items.detect{|i| i.item_type == '#{type_many}' && i.position == position }; r}
201
- end
202
- END
203
- # for each item type this many times
204
- count.times do |id|
205
- position = id + 1
206
- # individual accessors
207
- options[:columns].each do |column|
208
- # create getter, setter, and config
209
- next if self.respond_to? "#{type_one}_#{column}_#{position}"
210
- class_eval <<-END, __FILE__, (__LINE__+1)
211
- def #{type_one}_#{column}_#{position}
212
- get_item_value("#{type_one}_#{column}_#{position}")
213
- end
214
- def #{type_one}_#{column}_#{position}=(value)
215
- set_item_value("#{type_one}_#{column}_#{position}", value)
216
- end
217
- def #{type_one}_#{column}_#{position}_options
218
- @#{type_one}_#{column}_#{position}_options ||= item_options[:#{type_many}].merge({ :item_type => '#{type_many}', :column => '#{column}', :position => #{position} })
219
- end
220
- END
221
- end
165
+ def create_item_accessors(_itemized_options)
166
+ _itemized_options.each do |type_many, options|
167
+ # items in this set
168
+ count = _itemized_options[type_many][:count]
169
+ # class_eval accessors
170
+ if count == 1 && options[:columns].count == 1
171
+ # create a single accessor if there is only one item and one type
172
+ create_one_accessor type_many, options[:columns].first
173
+ else
174
+ # create a many accessors if there are multiple items or types
175
+ create_many_accessors type_many, options[:columns], count
222
176
  end
223
177
  end
224
178
 
225
179
  end
180
+
181
+ def create_one_accessor(type_many, column)
182
+ type_one = type_many.to_s.singularize
183
+ return if self.respond_to? "#{type_one}"
184
+ class_eval <<-END, __FILE__, (__LINE__+1)
185
+ def #{type_one}
186
+ get_item_value("#{type_one}")
187
+ end
188
+ def #{type_one}=(value)
189
+ set_item_value("#{type_one}", value)
190
+ end
191
+ def #{type_one}_options
192
+ @#{type_one}_options ||= itemized_options[:#{type_many}].merge({ :item_type => '#{type_many}', :column => '#{column}', :position => 1 })
193
+ end
194
+ END
195
+ end
196
+
197
+ def create_many_accessors(type_many, columns, count)
198
+ type_one = type_many.to_s.singularize
199
+ # for each item type this many times
200
+ count.times do |id|
201
+ position = id + 1
202
+ # individual accessors
203
+ columns.each do |column|
204
+ # create getter, setter, and config
205
+ next if self.respond_to? "#{type_one}_#{column}_#{position}"
206
+ class_eval <<-END, __FILE__, (__LINE__+1)
207
+ def #{type_one}_#{column}_#{position}
208
+ get_item_value("#{type_one}_#{column}_#{position}")
209
+ end
210
+ def #{type_one}_#{column}_#{position}=(value)
211
+ set_item_value("#{type_one}_#{column}_#{position}", value)
212
+ end
213
+ def #{type_one}_#{column}_#{position}_options
214
+ @#{type_one}_#{column}_#{position}_options ||= itemized_options[:#{type_many}].merge({ :item_type => '#{type_many}', :column => '#{column}', :position => #{position} })
215
+ end
216
+ END
217
+ end
218
+ end
219
+
220
+ end
226
221
 
227
222
 
228
223
  # ITEM GETTER & SETTER
@@ -247,14 +242,14 @@ module ActsAsItemized
247
242
  # get through delegate, if defined
248
243
  return self.send(options[:through]).send(key) if options[:through] && self.respond_to?(options[:through]) && !self.send(options[:through]).blank?
249
244
  # get through itemized_item record
250
- return nil unless item = items.detect{|i| i.item_type == options[:item_type] && i.position == options[:position] }
245
+ return nil unless item = itemized_items.detect{|i| i.item_type == options[:item_type] && i.position == options[:position] }
251
246
  item.send options[:column]
252
247
  end
253
248
 
254
249
  def update_or_create_item(key, value)
255
250
  options = self.send("#{key}_options")
256
251
  # find or create
257
- item = items.detect{|i| i.item_type == options[:item_type] && i.position == options[:position]} || create_item(options[:item_type], options[:position])
252
+ item = itemized_items.detect{|i| i.item_type == options[:item_type] && i.position == options[:position]} || create_item(options[:item_type], options[:position])
258
253
  # update
259
254
  item.send("#{options[:column]}=", value)
260
255
  item.save
@@ -262,10 +257,9 @@ module ActsAsItemized
262
257
 
263
258
  def create_item(item_type, position, conditions = {})
264
259
  record = conditions.merge({:item_type => item_type.to_s, :position => position})
265
- items.create(record)
260
+ itemized_items.create(record)
266
261
  end
267
-
268
-
262
+
269
263
  end
270
264
 
271
265
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: acts_as_itemized
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.1.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Blake Hilscher