Class: Tag

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/tag.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cloud_bandObject

Returns the value of attribute cloud_band.



4
5
6
# File 'app/models/tag.rb', line 4

def cloud_band
  @cloud_band
end

#cloud_sizeObject

Returns the value of attribute cloud_size.



4
5
6
# File 'app/models/tag.rb', line 4

def cloud_size
  @cloud_size
end

Class Method Details

.banded(tags = Tag.most_popular(100), bands = 6) ⇒ Object

applies the usual cloud-banding algorithm to a set of tags with use_count



204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'app/models/tag.rb', line 204

def self.banded(tags=Tag.most_popular(100), bands=6)
  if tags
    count = tags.map{|t| t.use_count.to_i}
    if count.any? # urgh. dodging named_scope count bug
      max_use = count.max
      min_use = count.min
      divisor = ((max_use - min_use) / bands) + 1
      tags.each do |tag|
        tag.cloud_band = (tag.use_count.to_i - min_use) / divisor
      end
      tags
    end
  end
end

.cloud_from(these) ⇒ Object



253
254
255
# File 'app/models/tag.rb', line 253

def self.cloud_from(these)
  for_cloud(attached_to(these))
end

.define_retrieval_methods(classname) ⇒ Object

adds retrieval methods for a taggable class to this class and to Tagging.



259
260
261
262
263
264
265
266
# File 'app/models/tag.rb', line 259

def self.define_retrieval_methods(classname)
  define_method "#{classname.downcase}_taggings".to_sym do
    self.taggings.of_a(classname)
  end
  define_method classname.downcase.pluralize.to_sym do
    classname.constantize.send :from_tag, self
  end
end

.for(title, or_create = true) ⇒ Object

finds or creates a tag with the supplied title



194
195
196
197
198
199
200
# File 'app/models/tag.rb', line 194

def self.for(title, or_create=true)
  if or_create
    self.sited? ? self.find_or_create_by_title_and_site_id(title, Page.current_site.id) : self.find_or_create_by_title(title)
  else
    self.sited? ? self.find_by_title_and_site_id(title, Page.current_site.id) : self.find_by_title(title)
  end
end

.for_cloud(tags) ⇒ Object

takes a list of tags and reaquires it from the database, this time with incidence. cheap call because it returns immediately if the list is already cloudable.



248
249
250
251
# File 'app/models/tag.rb', line 248

def self.for_cloud(tags)
  return tags if tags.empty? || tags.first.cloud_size
  sized(in_this_list(tags).with_count)
end

.from_list(list = [], or_create = true) ⇒ Object

turns an array or comma-separated string of tag titles into a list of tag objects, creating if specified



183
184
185
186
# File 'app/models/tag.rb', line 183

def self.from_list(list=[], or_create=true)
  list = list.split(/[,;]\s*/) if String === list
  list.uniq.map {|t| self.for(t, or_create) }.select{|t| !t.nil? } if list && list.any?
end

.sited?Boolean

returns true if tags are site-scoped

Returns:

  • (Boolean)


177
178
179
# File 'app/models/tag.rb', line 177

def self.sited?
  !reflect_on_association(:site).nil?
end

.sized(tags = Tag.most_popular(100), threshold = 0, biggest = 1.0, smallest = 0.4) ⇒ Object

applies a more sophisticated logarithmic weighting algorithm to a set of tags. derived from here: stackoverflow.com/questions/604953/what-is-the-correct-algorthm-for-a-logarthmic-distribution-curve-between-two-poin



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'app/models/tag.rb', line 223

def self.sized(tags=Tag.most_popular(100), threshold=0, biggest=1.0, smallest=0.4)
  if tags
    counts = tags.map{|t| t.use_count.to_i}
    if counts.any?
      max = counts.max
      min = counts.min
      if max == min
        tags.each do |tag|
          tag.cloud_size = sprintf("%.2f", biggest/2 + smallest/2)
        end
      else
        steepness = Math.log(max - (min-1))/(biggest - smallest)
        tags.each do |tag|
          offset = Math.log(tag.use_count.to_i - (min-1))/steepness
          tag.cloud_size = sprintf("%.2f", smallest + offset)
        end
      end
      tags
    end
  end
end

.to_list(tags = []) ⇒ Object



188
189
190
# File 'app/models/tag.rb', line 188

def self.to_list(tags=[])
  tags.uniq.map(&:title).join(',')
end

Instance Method Details

#<=>(othertag) ⇒ Object



122
123
124
# File 'app/models/tag.rb', line 122

def <=>(othertag)
  String.natcmp(self.title, othertag.title)   # natural sort method defined in lib/natcomp.rb
end

#assetsObject

Returns a list of all the assets tagged with this tag.



157
158
159
# File 'app/models/tag.rb', line 157

def assets
  Asset.from_tags([self])
end

#clean_titleObject

Standardises formatting of tag name in urls



139
140
141
# File 'app/models/tag.rb', line 139

def clean_title
  Rack::Utils.escape(title)
end

#coincident_tagsObject

Returns a list of all the tags that have been applied alongside this one.



171
172
173
# File 'app/models/tag.rb', line 171

def coincident_tags
  self.class.coincident_with(self)
end

#pagesObject

Returns a list of all the pages tagged with this tag.



151
152
153
# File 'app/models/tag.rb', line 151

def pages
  Page.from_tags([self])
end

#structuralObject Also known as: structural?

returns true if this tag points to a page



132
133
134
# File 'app/models/tag.rb', line 132

def structural
  !page_id.nil?
end

#taggedObject

Returns a list of all the objects tagged with this tag. We can’t do this in SQL because it’s polymorphic (and has_many_polymorphs makes my skin itch)



145
146
147
# File 'app/models/tag.rb', line 145

def tagged
  taggings.map {|t| t.tagged}
end

#to_sObject



126
127
128
# File 'app/models/tag.rb', line 126

def to_s
  title
end