Class: ToughGuy::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/toughguy/model.rb

Direct Known Subclasses

MappedModel, SingletonModel

Constant Summary collapse

@@db_map =
{}
@@connection =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values = {}, collection = nil) ⇒ Model

Returns a new instance of Model.



5
6
7
8
# File 'lib/toughguy/model.rb', line 5

def initialize(values = {}, collection = nil)
  @values = values.symbolize_keys
  @collection = collection
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object



13
14
15
16
17
18
19
# File 'lib/toughguy/model.rb', line 13

def method_missing(m, *args)
  if m.to_s =~ /^(.+)=$/
    @values[$1.to_sym] = args[0]
  else
    @values[m]
  end
end

Instance Attribute Details

#collectionObject

Returns the value of attribute collection.



3
4
5
# File 'lib/toughguy/model.rb', line 3

def collection
  @collection
end

#valuesObject

Returns the value of attribute values.



3
4
5
# File 'lib/toughguy/model.rb', line 3

def values
  @values
end

Class Method Details

.[](opts) ⇒ Object Also known as: find



159
160
161
162
163
164
# File 'lib/toughguy/model.rb', line 159

def [](opts)
  unless opts.is_a?(Hash)
    opts = {_id: opts}
  end
  first(opts)
end

.add_index(spec, opts = {}) ⇒ Object



133
134
135
136
# File 'lib/toughguy/model.rb', line 133

def add_index(spec, opts={})
  @indexes ||= []
  @indexes << [spec, opts]
end

.all(opts = {}) ⇒ Object



192
193
194
# File 'lib/toughguy/model.rb', line 192

def all(opts = {})
  query(opts).to_a
end

.bulk(&block) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/toughguy/model.rb', line 124

def bulk(&block)
  reentered = @bulk
  @bulk = collection.initialize_ordered_bulk_op unless reentered
  block.call
  @bulk.execute unless reentered || @bulk.ops.empty?
ensure
  @bulk = nil unless reentered
end

.collectionObject



219
220
221
# File 'lib/toughguy/model.rb', line 219

def collection
  @collection ||= database[collection_name]
end

.collection_nameObject



233
234
235
# File 'lib/toughguy/model.rb', line 233

def collection_name
  @collection_name ||= to_table_name
end

.connectionObject



352
353
354
# File 'lib/toughguy/model.rb', line 352

def connection
  @@connection
end

.connection=(c) ⇒ Object



356
357
358
# File 'lib/toughguy/model.rb', line 356

def connection=(c)
  @@connection = c
end

.count(opts = {}) ⇒ Object



188
189
190
# File 'lib/toughguy/model.rb', line 188

def count(opts = {})
  query(opts).count
end

.create(values = {}) ⇒ Object



153
154
155
156
157
# File 'lib/toughguy/model.rb', line 153

def create(values = {})
  o = new(values)
  o.save
  o
end

.databaseObject Also known as: db



276
277
278
# File 'lib/toughguy/model.rb', line 276

def database
  @database
end

.database=(db) ⇒ Object



284
285
286
287
288
289
290
291
292
293
294
# File 'lib/toughguy/model.rb', line 284

def database=(db)
  if db.is_a?(String)
    db = (@@db_map[db] = connection[db])
  end
  @database = db
  # update also for mapped model
  if self == ToughGuy::Model
    ToughGuy::MappedModel.database = db
    ToughGuy::SingletonModel.database = db
  end
end

.db_class_name(db_key) ⇒ Object



300
301
302
303
# File 'lib/toughguy/model.rb', line 300

def db_class_name(db_key)
  name = (db_key =~ /_(.+)/) && $1.gsub(/[^a-z0-9]/, '').capitalize
  "P_#{name}"
end

.db_key(db) ⇒ Object



296
297
298
# File 'lib/toughguy/model.rb', line 296

def db_key(db)
  db.is_a?(String) ? db : db.name
end

.delete(selector) ⇒ Object



245
246
247
248
249
250
251
# File 'lib/toughguy/model.rb', line 245

def delete(selector)
  if @bulk
    @bulk.find(selector).remove
  else
    q(selector).remove
  end
end

.delete_allObject



241
242
243
# File 'lib/toughguy/model.rb', line 241

def delete_all
  collection.remove
end

.destroy_allObject



253
254
255
# File 'lib/toughguy/model.rb', line 253

def destroy_all
  q.each {|d| d.destroy}
end

.dropObject



257
258
259
# File 'lib/toughguy/model.rb', line 257

def drop
  collection.drop
end

.each(*args, &block) ⇒ Object



196
197
198
# File 'lib/toughguy/model.rb', line 196

def each(*args, &block)
  query.each(*args, &block)
end

.ensure_index(spec, opts = {}) ⇒ Object



138
139
140
141
# File 'lib/toughguy/model.rb', line 138

def ensure_index(spec, opts={})
  add_index(spec, opts)
  collection.create_index(spec, opts)
end

.first(opts = {}) ⇒ Object



208
209
210
# File 'lib/toughguy/model.rb', line 208

def first(opts = {})
  query(opts).first
end

.inherited(subclass) ⇒ Object



342
343
344
# File 'lib/toughguy/model.rb', line 342

def inherited(subclass)
  subclass.database = database
end

.limit(l, skip = 0) ⇒ Object



180
181
182
# File 'lib/toughguy/model.rb', line 180

def limit(l, skip = 0)
  query.limit(l).skip(0)
end

.load(values) ⇒ Object



149
150
151
# File 'lib/toughguy/model.rb', line 149

def load(values)
  new(values).tap {|o| o.after_load}
end

.map(key = nil, &block) ⇒ Object



200
201
202
# File 'lib/toughguy/model.rb', line 200

def map(key = nil, &block)
  query.map(key, &block)
end

.map_keys(hash) ⇒ Object



212
213
214
215
216
217
# File 'lib/toughguy/model.rb', line 212

def map_keys(hash)
  hash.each do |key, short_key|
    define_method(key) {@values[short_key]}
    define_method(:"#{key}=") {|v| @values[short_key] = v}
  end
end

.mapped_db_classesObject



346
347
348
# File 'lib/toughguy/model.rb', line 346

def mapped_db_classes
  (@subclass_map || {}).values.unshift(self)
end

.paginate(opts) ⇒ Object



184
185
186
# File 'lib/toughguy/model.rb', line 184

def paginate(opts)
  query.paginate(opts)
end

.query(opts = {}) ⇒ Object Also known as: q, where, filter



168
169
170
# File 'lib/toughguy/model.rb', line 168

def query(opts = {})
  ToughGuy::Query.new(self).where(opts)
end

.recreate_indexesObject



143
144
145
146
147
# File 'lib/toughguy/model.rb', line 143

def recreate_indexes
  if @indexes
    @indexes.each {|idx| ensure_index(*idx)}
  end
end

.remove_class_with_db(db) ⇒ Object



332
333
334
335
336
337
338
339
340
# File 'lib/toughguy/model.rb', line 332

def remove_class_with_db(db)
  @subclass_map ||= {}
  key = db_key(db)
  class_name = db_class_name(key)
  c = @subclass_map.delete(key)
  if class_name
    send(:remove_const, class_name) if const_defined?(class_name, false)
  end
end

.set_collection(c) ⇒ Object



223
224
225
# File 'lib/toughguy/model.rb', line 223

def set_collection(c)
  @collection = c
end

.set_collection_name(n) ⇒ Object



237
238
239
# File 'lib/toughguy/model.rb', line 237

def set_collection_name(n)
  @collection_name = n
end

.sort(*args) ⇒ Object



176
177
178
# File 'lib/toughguy/model.rb', line 176

def sort(*args)
  query.sort(*args)
end

.statsObject



270
271
272
# File 'lib/toughguy/model.rb', line 270

def stats
  collection.stats
end

.subclass_with_db(db, db_key) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/toughguy/model.rb', line 305

def subclass_with_db(db, db_key)
  c = Class.new(self).tap do |klass|
    klass.database = db
    klass.set_collection_name(collection_name)
    if @indexes
      @indexes.each {|idx| klass.ensure_index(*idx)}
    end
  end
  
  # create proper class name
  class_name = db_class_name(db_key)
  if class_name
    # remove class const before defining it in order to prevent warning
    send(:remove_const, class_name) if const_defined?(class_name, false)
    const_set(class_name, c)
  end
    
  c
end

.to_table_nameObject



227
228
229
230
231
# File 'lib/toughguy/model.rb', line 227

def to_table_name
  parts = name.downcase.split('::')
  parts.push(parts.pop.pluralize)
  parts.join('.')
end

.update(*args) ⇒ Object



261
262
263
264
265
266
267
268
# File 'lib/toughguy/model.rb', line 261

def update(*args)
  if @bulk
    @bulk.find(args[0]).update(args[1])
  else
    collection.update(*args)
  end
  # (@bulk || collection).update(*args)
end

.with_db(db) ⇒ Object



325
326
327
328
329
330
# File 'lib/toughguy/model.rb', line 325

def with_db(db)
  key = db_key(db)
  return self if key == db_key(self.db)
  @subclass_map ||= {}
  @subclass_map[key] ||= subclass_with_db(db, key)
end

Instance Method Details

#==(obj) ⇒ Object



115
116
117
# File 'lib/toughguy/model.rb', line 115

def ==(obj)
  (obj.class == model) && (obj.values == @values)
end

#[](k) ⇒ Object



39
40
41
# File 'lib/toughguy/model.rb', line 39

def [](k)
  @values[k]
end

#[]=(k, v) ⇒ Object



43
44
45
# File 'lib/toughguy/model.rb', line 43

def []=(k, v)
  @values[k] = v
end

#after_createObject



58
59
# File 'lib/toughguy/model.rb', line 58

def after_create
end

#after_destroyObject



92
93
# File 'lib/toughguy/model.rb', line 92

def after_destroy
end

#after_loadObject



10
11
# File 'lib/toughguy/model.rb', line 10

def after_load
end

#before_createObject



55
56
# File 'lib/toughguy/model.rb', line 55

def before_create
end

#before_destroyObject



89
90
# File 'lib/toughguy/model.rb', line 89

def before_destroy
end

#bulk(&block) ⇒ Object



35
36
37
# File 'lib/toughguy/model.rb', line 35

def bulk(&block)
  model.bulk(&block)
end

#databaseObject



25
26
27
# File 'lib/toughguy/model.rb', line 25

def database
  @database ||= collection.db
end

#dbObject



29
30
31
# File 'lib/toughguy/model.rb', line 29

def database
  @database ||= collection.db
end

#deleteObject



85
86
87
# File 'lib/toughguy/model.rb', line 85

def delete
  model.delete(_id: id)
end

#destroyObject



99
100
101
102
103
104
# File 'lib/toughguy/model.rb', line 99

def destroy
  before_destroy
  @destroyed = true
  delete
  after_destroy
end

#destroyed?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/toughguy/model.rb', line 95

def destroyed?
  @destroyed
end

#exists?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/toughguy/model.rb', line 119

def exists?
  model.find(id) != nil
end

#idObject



47
48
49
# File 'lib/toughguy/model.rb', line 47

def id
  @_id ||= @values[:_id]
end

#inspectObject



110
111
112
113
# File 'lib/toughguy/model.rb', line 110

def inspect
  v = values.exclude(:_id).map {|k, v| "#{k}: #{v.inspect}"}.join(', ')
  "#<#{model.name}:#{id || 'unsaved'} #{v}>"
end

#modelObject



31
32
33
# File 'lib/toughguy/model.rb', line 31

def model
  self.class
end

#new?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/toughguy/model.rb', line 51

def new?
  !@values[:_id]
end

#refreshObject



80
81
82
83
# File 'lib/toughguy/model.rb', line 80

def refresh
  @values = collection.find(_id: id).first.symbolize_keys
  self
end

#saveObject



61
62
63
64
65
66
67
68
69
# File 'lib/toughguy/model.rb', line 61

def save
  if new?
    before_create
    values[:_id] = collection.insert(values)
    after_create
  else
    self.class.update({_id: id}, values.exclude(:_id))
  end
end

#set(hash) ⇒ Object



75
76
77
78
# File 'lib/toughguy/model.rb', line 75

def set(hash)
  model.update({_id: id}, '$set' => hash)
  @values.merge!(hash.symbolize_keys)
end

#to_sObject



106
107
108
# File 'lib/toughguy/model.rb', line 106

def to_s
  "#<#{model.name}:#{id || 'unsaved'}>"
end

#update(hash) ⇒ Object



71
72
73
# File 'lib/toughguy/model.rb', line 71

def update(hash)
  model.update({_id: id}, hash)
end