acts_as_itemized 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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