Class: DocumentFile::Collection

Inherits:
Array
  • Object
show all
Defined in:
lib/document_file/collection.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#totalObject



7
8
9
# File 'lib/document_file/collection.rb', line 7

def total
  @total || length
end

Class Method Details

.ensure_document(document) ⇒ Object

Raises:

  • (ArgumentError)


33
34
35
# File 'lib/document_file/collection.rb', line 33

def self.ensure_document(document)
  raise ArgumentError unless document.class.include? DocumentFile
end

.new_with_finders(*args) ⇒ Object Also known as: new



18
19
20
21
22
23
24
25
26
27
# File 'lib/document_file/collection.rb', line 18

def new_with_finders(*args)
  collection = new_without_finders(*args)
  collection.each do |document|
    self.ensure_document(document)
    attributes_hash = document.data.merge({'file_name' => document.file_name})
    attributes_hash.delete 'date'
    collection.define_dynamic_finders attributes_hash
  end
  collection
end

Instance Method Details

#<<(document) ⇒ Object



11
12
13
14
15
# File 'lib/document_file/collection.rb', line 11

def <<(document)
  self.class.ensure_document(document)
  define_dynamic_finders document.data
  super
end

#define_by_array_attribute(array_attribute) ⇒ Object

Defines a by attribute finder for Array attributes, e.g. MyDocument.by_tags

=> {
     "tag_1" => [document_1, document_3],
     "tag_2" => [document_2]
   }


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/document_file/collection.rb', line 68

def define_by_array_attribute(array_attribute)
  by_attribute = <<-eos
    def by_#{array_attribute}
      #{array_attribute}_items = {}
      each do |document|
        document.#{array_attribute}.each do |single_item|
          if #{array_attribute}_items.has_key? single_item
            #{array_attribute}_items[single_item] << document
          else
            #{array_attribute}_items[single_item] = Collection.new [document]
          end
        end if document.#{array_attribute}
      end
      #{array_attribute}_items
    end
  eos
  instance_eval by_attribute
end

#define_dynamic_finders(attributes_hash) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/document_file/collection.rb', line 53

def define_dynamic_finders(attributes_hash)
  attributes_hash.each do |attribute, value|
    define_find_all_by attribute, value
    define_find_by attribute

    define_by_array_attribute(attribute) if value.is_a? Array
  end
end

#define_find_all_by(attribute, value) ⇒ Object

Finds documents by a specific Array attribute value , e.g. MyDocument.find_all_by_tag(‘my_tag’) => [document_1, document_2, …]



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/document_file/collection.rb', line 89

def define_find_all_by(attribute, value)
  if value.is_a? Array
    singular_attribute = ActiveSupport::Inflector.singularize attribute
  else
    singular_attribute = attribute
  end
  find_all_by_attribute = <<-eos
    def find_all_by_#{singular_attribute}(attribute, options = {})
      documents = if respond_to?(:by_#{attribute})
        by_#{attribute}[attribute]
      else
        select do |document|
          if document.respond_to? :#{attribute}
            document.#{attribute} == attribute
          else
            false
          end
        end
      end

      self.class.new(documents).offset_and_limitize(options[:offset], options[:limit])
    end
  eos
  instance_eval find_all_by_attribute
end

#define_find_by(attribute) ⇒ Object

Defines an attribute finder for one document, e.g. MyDocument.find_by_title(‘some_title’) => some_document



117
118
119
120
121
122
123
124
125
# File 'lib/document_file/collection.rb', line 117

def define_find_by(attribute)
  find_by_attribute = <<-eos
    def find_by_#{attribute}(attribute)
      documents = find_all_by_#{attribute}(attribute)
      documents.any? ? documents.first : nil
    end
  eos
  instance_eval find_by_attribute
end

#find_all_by_date(*args) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/document_file/collection.rb', line 37

def find_all_by_date(*args)
  return if args.size == 0

  date_parts = %w(year month day)
  docs = self
  args.size.times do |i|
    next if args[i] == '*'
    docs = docs.select { |doc| doc.date.send(date_parts[i]) == args[i] }
  end
  self.class.new docs
end

#find_by_date(*args) ⇒ Object



49
50
51
# File 'lib/document_file/collection.rb', line 49

def find_by_date(*args)
  find_all_by_date(*args).first
end

#offset_and_limitize(offset, limit) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/document_file/collection.rb', line 127

def offset_and_limitize(offset, limit)
  documents = self
  total_size = documents.length
  if offset
    documents = documents.last(length - offset)
  end
  if limit
    documents = documents.first(limit)
  end
  self.class.new(documents).tap do |col|
    col.total = total_size
  end
end