Class: Tagtical::Tag::Type

Inherits:
String
  • Object
show all
Defined in:
lib/tagtical/tag.rb

Constant Summary collapse

BASE =

“tag” should always correspond with demodulize name of the base Tag class (ie Tagtical::Tag).

"tag".freeze
@@cache =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str, taggable_class, options = {}) ⇒ Type

Returns a new instance of Type.



169
170
171
172
173
# File 'lib/tagtical/tag.rb', line 169

def initialize(str, taggable_class, options={})
  options.each { |k, v| instance_variable_set("@#{k}", v) }
  @taggable_class = taggable_class
  super(str)
end

Instance Attribute Details

#taggable_classObject (readonly)

Returns the value of attribute taggable_class.



167
168
169
# File 'lib/tagtical/tag.rb', line 167

def taggable_class
  @taggable_class
end

Class Method Details

.find(input, taggable_class) ⇒ Object Also known as: []



179
180
181
182
183
184
185
186
# File 'lib/tagtical/tag.rb', line 179

def find(input, taggable_class)
  case input
  when self then input
  when String, Symbol then new(sanitize(input), taggable_class)
  when Hash  then input.map { |input, klass| new(sanitize(input), taggable_class, :klass => klass) }
  when Array then input.map { |c| find(c, taggable_class) }.flatten
  end
end

.register(inputs, taggable_class) ⇒ Object

Stores the tag types in memory



190
191
192
193
194
195
# File 'lib/tagtical/tag.rb', line 190

def register(inputs, taggable_class)
  find(inputs, taggable_class).each do |tag_type|
    cache[tag_type] ||= []
    cache[tag_type] << tag_type unless cache[tag_type].include?(tag_type)
  end
end

Instance Method Details

#==(input) ⇒ Object



214
215
216
217
218
219
220
# File 'lib/tagtical/tag.rb', line 214

def ==(input)
  case input
  when self.class then comparable_array==input.comparable_array
  when String then input==self
  else false
  end
end

#active_record_sti_levelObject

Returns the level from which it extends from Tagtical::Tag



312
313
314
315
316
317
318
319
320
321
# File 'lib/tagtical/tag.rb', line 312

def active_record_sti_level
  @active_record_sti_level ||= begin
    count, current_class = 0, klass
    while !current_class.descends_from_active_record?
      current_class = current_class.superclass
      count += 1
    end
    count
  end
end

#base?Boolean

Returns:

  • (Boolean)


292
293
294
# File 'lib/tagtical/tag.rb', line 292

def base?
  BASE==self
end

#comparable_arrayObject



210
211
212
# File 'lib/tagtical/tag.rb', line 210

def comparable_array
  [to_s, klass]
end

#finder_type_condition(*args) ⇒ Object

Leverages current type_condition logic from ActiveRecord while also allowing for type conditions when no Tag subclass is defined. Also, it builds the type condition for STI inheritance.

Options:

<tt>sql</tt> - Set to true to return sql string. Set to :append to return a sql string which can be appended as a condition.
<tt>only</tt> - An array of the following: :parents, :current, :children. Will construct conditions to query the current, parent, and/or children STI classes.


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/tagtical/tag.rb', line 229

def finder_type_condition(*args)
  options = convert_finder_type_arguments(*args)
  type = convert_type_options(options[:scope])

  # If we want [:current, :children] or [:current, :children, :parents] and we don't need the finder type condition,
  # then that means we don't need a condition at all since we are at the top-level sti class and we are essentially
  # searching the whole range of sti classes.
  if klass && !klass.finder_needs_type_condition?
    type.delete(:parents) # we are at the topmost level.
    type = [] if type==[:current, :children] # no condition is required if we want the current AND the children.
  end

  sti_names = []
  if type.include?(:current)
    sti_names << klass.sti_name
  end
  if type.include?(:children) && klass
    sti_names.concat(klass.descendants.map(&:sti_name))
  end
  if type.include?(:parents) && klass # include searches up the STI chain
    parent_class = klass.superclass
    while parent_class <= Tagtical::Tag
      sti_names << parent_class.sti_name
      parent_class = parent_class.superclass
    end
  end

  sti_column = Tagtical::Tag.arel_table[Tagtical::Tag.inheritance_column]
  condition = sti_names.inject(nil) do |conds, sti_name|
    cond = sti_column.eq(sti_name)
    conds.nil? ? cond : conds.or(cond)
  end

  if condition && options[:sql]
    condition = condition.to_sql
    condition.insert(0, " AND ") if options[:sql]==:append
  end
  condition
end

#has_many_nameObject Also known as: scope_name



296
297
298
# File 'lib/tagtical/tag.rb', line 296

def has_many_name
  pluralize.to_sym
end

#klassObject

Return the Tag subclass



288
289
290
# File 'lib/tagtical/tag.rb', line 288

def klass
  @klass ||= find_tag_class!
end

#match?(input) ⇒ Boolean

Matches the string against the type after sanitizing it.

Returns:

  • (Boolean)


206
207
208
# File 'lib/tagtical/tag.rb', line 206

def match?(input)
  self==self.class.send(:sanitize, input)
end

#scoping(*args, &block) ⇒ Object

Accepts:

scoping(:<=)
scoping(:scoping => :<=)


272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/tagtical/tag.rb', line 272

def scoping(*args, &block)
  finder_type_condition = finder_type_condition(*args)
  if block_given?
    if finder_type_condition
      Tagtical::Tag.send(:with_scope, :find => Tagtical::Tag.where(finder_type_condition), :create => {:type => klass.sti_name}) do
        Tagtical::Tag.instance_exec(&block)
      end
    else
      Tagtical::Tag.instance_exec(&block)
    end
  else
    Tagtical::Tag.send(*(finder_type_condition ? [:where, finder_type_condition] : :unscoped))
  end
end

#tag_list_ivar(*args) ⇒ Object



307
308
309
# File 'lib/tagtical/tag.rb', line 307

def tag_list_ivar(*args)
  "@#{tag_list_name(*args)}"
end

#tag_list_name(prefix = nil) ⇒ Object



301
302
303
304
305
# File 'lib/tagtical/tag.rb', line 301

def tag_list_name(prefix=nil)
  prefix = prefix.to_s.dup
  prefix << "_" unless prefix.blank?
  "#{prefix}#{self}_list"
end