rocket_tag 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -67,6 +67,13 @@ of 'tags_count'
67
67
  model.tagged_similar :on => "skills"
68
68
  model.tagged_similar :on => "habits"
69
69
 
70
+ The two cases of tagged_similar below are functionally identical because there are
71
+ only two contexts specified on the class. If there were three or more contexts specified
72
+ then the two below would not be identical.
73
+
74
+ model.tagged_similar :on => ["skills", "habits"]
75
+ model.tagged_similar
76
+
70
77
  Find similar models based on tags on every context and return in decending order
71
78
  of 'tags_count'. Note that each tag is still scoped according to it's context
72
79
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2
1
+ 0.5.3
@@ -108,39 +108,24 @@ module RocketTag
108
108
  @contexts[context.to_sym] = list
109
109
  end
110
110
 
111
- def read_context context
111
+ def tags_for_context context
112
112
  @contexts ||= {}
113
113
  @contexts[context.to_sym] || []
114
114
  end
115
115
 
116
-
117
116
  def tagged_similar options = {}
118
117
  context = options.delete :on
119
- if context
120
- raise Exception.new("#{context} is not a valid tag context for #{self.class}") unless self.class.rocket_tag.contexts.include? context
121
- end
122
- if context
123
- contexts = [context]
124
- else
125
- contexts = self.class.rocket_tag.contexts
126
- end
127
-
128
- if contexts.size > 1
129
- contexts = contexts.delete :tag
130
- end
131
118
 
132
- contexts = contexts.reject do |c|
133
- send(c.to_sym).size == 0
134
- end
119
+ contexts = self.class.normalize_contexts(context, self.class.rocket_tag.contexts)
135
120
 
136
- conditions = contexts.map do |context|
137
- _tags = send context.to_sym
121
+ condition = contexts.reject do |c|
122
+ tags_for_context(c).size == 0
123
+ end.map do |context|
138
124
  self.class.squeel do
139
- (tags.name.in(_tags) & (taggings.context == context.to_s))
125
+ tags.name.in(my{tags_for_context(context)}) &
126
+ (taggings.context == context.to_s)
140
127
  end
141
- end
142
-
143
- condition = conditions.inject do |s, t|
128
+ end.inject do |s, t|
144
129
  s | t
145
130
  end
146
131
 
@@ -168,7 +153,13 @@ module RocketTag
168
153
  # the relation instead of passing the rel parameter in
169
154
  # however my tests fails with wrong counts. This is
170
155
  # not so elegant
171
- def count_tags(rel)
156
+ #
157
+ # rel can be passed as the last expression in a block
158
+ # if desired.
159
+ def count_tags(rel=nil)
160
+ if block_given?
161
+ rel = yield
162
+ end
172
163
  rel.select('*').
173
164
  select{count(~id).as(tags_count)}.
174
165
  group_by_all_columns.
@@ -176,36 +167,54 @@ module RocketTag
176
167
  isolate_group_by_as(self)
177
168
  end
178
169
 
170
+ def is_valid_context? context
171
+ rocket_tag.contexts.include? context
172
+ end
173
+
174
+ def normalize_contexts(context, default_if_nil = [])
175
+ contexts = if context
176
+ if context.class == Array
177
+ context
178
+ else
179
+ [context]
180
+ end
181
+ else
182
+ default_if_nil
183
+ end
184
+
185
+ validate_contexts(contexts)
186
+
187
+ contexts
188
+ end
189
+
190
+ # Verify contexts are valid for the taggable type
191
+ def validate_contexts contexts
192
+ contexts.each do |context|
193
+ unless self.is_valid_context? context
194
+ raise Exception.new("#{context} is not a valid tag context for #{self}")
195
+ end
196
+ end
197
+ end
198
+
179
199
  # Filters tags according to
180
200
  # context. context param can
181
201
  # be either a single context
182
202
  # id or an array of context ids
183
203
  def with_tag_context context
184
- if context
185
- if context
186
- if context.class == Array
187
- contexts = context
188
- else
189
- contexts = [context]
190
- end
191
- else
192
- contexts = []
193
- end
204
+ contexts = normalize_contexts(context)
194
205
 
195
- conditions = contexts.map do |context|
206
+ condition = if contexts
207
+
208
+ contexts.map do |context|
196
209
  squeel do
197
210
  (taggings.context == context.to_s)
198
211
  end
199
- end
200
-
201
- condition = conditions.inject do |s, t|
212
+ end.inject do |s, t|
202
213
  s | t
203
214
  end
204
215
 
205
- where{condition}
206
- else
207
- where{ }
208
216
  end
217
+
209
218
  end
210
219
 
211
220
 
@@ -224,23 +233,16 @@ module RocketTag
224
233
  # along with an extra column :tags_count.
225
234
  def tagged_with tags_list, options = {}
226
235
 
227
- r = joins{tags}.
236
+ r = count_tags do
237
+ joins{tags}.
228
238
  where{tags.name.in(tags_list)}.
229
- with_tag_context(options.delete :on)
230
-
231
-
232
- r = count_tags(r)
239
+ where(with_tag_context(options.delete(:on)))
240
+ end
233
241
 
234
242
  if options.delete :all
235
- r = r.where{tags_count==tags_list.length}
243
+ r.where{tags_count==tags_list.length}
236
244
  elsif min = options.delete(:min)
237
- r = r.where{tags_count>=min}
238
- end
239
-
240
- if options.delete :sifter
241
- squeel do
242
- id.in(r.select{"id"})
243
- end
245
+ r.where{tags_count>=min}
244
246
  else
245
247
  r
246
248
  end
@@ -251,13 +253,12 @@ module RocketTag
251
253
  # for given model with an extra column :tags_count.
252
254
  def popular_tags options={}
253
255
 
254
- r =
255
- RocketTag::Tag.
256
+ r = count_tags do
257
+ RocketTag::Tag.
256
258
  joins{taggings}.
257
- with_tag_context(options.delete :on).
259
+ where(with_tag_context(options.delete(:on))).
258
260
  by_taggable_type(self)
259
-
260
- r = count_tags(r)
261
+ end
261
262
 
262
263
  if min = options.delete(:min)
263
264
  r = r.where{tags_count>=min}
@@ -320,10 +321,6 @@ module RocketTag
320
321
  alias_method_chain :reload, :tags
321
322
  end
322
323
 
323
- if contexts.blank?
324
- contexts = [:tag]
325
- end
326
-
327
324
  rocket_tag.contexts += contexts
328
325
 
329
326
  setup_for_rocket_tag
@@ -352,7 +349,7 @@ module RocketTag
352
349
  # Return an array of RocketTag::Tags for the context
353
350
  define_method "#{context}" do
354
351
  cache_tags
355
- read_context(context)
352
+ tags_for_context(context)
356
353
  end
357
354
 
358
355
 
data/rocket_tag.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "rocket_tag"
8
- s.version = "0.5.2"
8
+ s.version = "0.5.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Brad Phelan"]
12
- s.date = "2012-06-29"
12
+ s.date = "2012-07-02"
13
13
  s.description = ""
14
14
  s.email = "bradphelan@xtargets.com"
15
15
  s.extra_rdoc_files = [
@@ -174,6 +174,11 @@ describe TaggableModel do
174
174
  it "should return similar items" do
175
175
  @t00.tagged_similar(:on => :skills).count.should == 3
176
176
  @t00.tagged_similar(:on => :languages).count.should == 3
177
+
178
+ @t00.tagged_similar(:on => [:languages, :skills]).count.should == 4
179
+
180
+ # Effectively similar to specifying all the contexts in
181
+ # the on clause
177
182
  @t00.tagged_similar.count.should == 4
178
183
  end
179
184
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rocket_tag
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.2
5
+ version: 0.5.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brad Phelan
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-06-29 00:00:00 Z
13
+ date: 2012-07-02 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -144,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
144
  requirements:
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- hash: -4599710415322138836
147
+ hash: 293230795738832648
148
148
  segments:
149
149
  - 0
150
150
  version: "0"