Class: SuperModel::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming
Includes:
ActiveModel::Conversion, ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml, Association::Model, Callbacks, Dirty, Observing, Validations
Defined in:
lib/supermodel/base.rb,
lib/supermodel/base.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Association::Model

included

Methods included from Dirty

#save_previous_changes

Methods included from Validations

#save_with_validation

Constructor Details

#initialize(attributes = {}) ⇒ Base

Returns a new instance of Base.



126
127
128
129
130
131
132
# File 'lib/supermodel/base.rb', line 126

def initialize(attributes = {})
  @new_record = true
  @attributes = {}.with_indifferent_access
  @attributes.merge!(known_attributes.inject({}) {|h, n| h[n] = nil; h })
  @changed_attributes = {}
  load(attributes)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_symbol, *arguments) ⇒ Object (private)

:nodoc:



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/supermodel/base.rb', line 282

def method_missing(method_symbol, *arguments) #:nodoc:
  method_name = method_symbol.to_s

  if method_name =~ /(=|\?)$/
    case $1
    when "="
      attribute_will_change!($`)
      attributes[$`] = arguments.first
    when "?"
      attributes[$`]
    end
  else
    return attributes[method_name] if attributes.include?(method_name)
    return nil if known_attributes.include?(method_name)
    super
  end
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



119
120
121
# File 'lib/supermodel/base.rb', line 119

def attributes
  @attributes
end

#new_record=(value) ⇒ Object (writeonly)

Sets the attribute new_record

Parameters:

  • value

    the value to set the attribute new_record to.



120
121
122
# File 'lib/supermodel/base.rb', line 120

def new_record=(value)
  @new_record = value
end

Class Method Details

.allObject



62
63
64
# File 'lib/supermodel/base.rb', line 62

def all
  collection.new(records.values.deep_dup)
end

.attributes(*attributes) ⇒ Object



15
16
17
# File 'lib/supermodel/base.rb', line 15

def attributes(*attributes)
  self.known_attributes += attributes.map(&:to_s)
end

.collection(&block) ⇒ Object



9
10
11
12
13
# File 'lib/supermodel/base.rb', line 9

def collection(&block)
  @collection ||= Class.new(Array)
  @collection.class_eval(&block) if block_given?
  @collection
end

.countObject



58
59
60
# File 'lib/supermodel/base.rb', line 58

def count
  records.length
end

.create(atts = {}) ⇒ Object

Create a new record. Example:

create(:name => "foo", :id => 1)


93
94
95
96
# File 'lib/supermodel/base.rb', line 93

def create(atts = {})
  rec = self.new(atts)
  rec.save && rec
end

.create!(*args) ⇒ Object



98
99
100
# File 'lib/supermodel/base.rb', line 98

def create!(*args)
  create(*args) || raise(InvalidRecord)
end

.delete_allObject

Removes all records without executing destroy callbacks.



86
87
88
# File 'lib/supermodel/base.rb', line 86

def delete_all
  records.clear
end

.destroy(id) ⇒ Object



74
75
76
# File 'lib/supermodel/base.rb', line 74

def destroy(id)
  find(id).destroy
end

.destroy_allObject

Removes all records and executes destory callbacks.



80
81
82
# File 'lib/supermodel/base.rb', line 80

def destroy_all
  all.each {|r| r.destroy }
end

.exists?(id) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/supermodel/base.rb', line 54

def exists?(id)
  records.has_key?(id)
end

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

Find record by ID, or raise.



38
39
40
41
# File 'lib/supermodel/base.rb', line 38

def find(id)
  item = raw_find(id)
  item && item.dup
end

.find_all_by_attribute(name, value) ⇒ Object

:nodoc:



28
29
30
31
# File 'lib/supermodel/base.rb', line 28

def find_all_by_attribute(name, value) #:nodoc:
  items = records.values.select {|r| r.send(name) == value }
  collection.new(items.deep_dup)
end

.find_by_attribute(name, value) ⇒ Object

:nodoc:



23
24
25
26
# File 'lib/supermodel/base.rb', line 23

def find_by_attribute(name, value) #:nodoc:
  item = records.values.find {|r| r.send(name) == value }
  item && item.dup
end

.firstObject



44
45
46
47
# File 'lib/supermodel/base.rb', line 44

def first
  item = records.values[0]
  item && item.dup
end

.lastObject



49
50
51
52
# File 'lib/supermodel/base.rb', line 49

def last
  item = records.values[-1]
  item && item.dup
end

.method_missing(method_symbol, *args) ⇒ Object

:nodoc:



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/supermodel/base.rb', line 102

def method_missing(method_symbol, *args) #:nodoc:
  method_name = method_symbol.to_s

  if method_name =~ /^find_by_(\w+)!/
    send("find_by_#{$1}", *args) || raise(UnknownRecord)
  elsif method_name =~ /^find_by_(\w+)/
    find_by_attribute($1, args.first)
  elsif method_name =~ /^find_or_create_by_(\w+)/
    send("find_by_#{$1}", *args) || create($1 => args.first)
  elsif method_name =~ /^find_all_by_(\w+)/
    find_all_by_attribute($1, args.first)
  else
    super
  end
end

.raw_find(id) ⇒ Object

:nodoc:



33
34
35
# File 'lib/supermodel/base.rb', line 33

def raw_find(id) #:nodoc:
  records[id] || raise(UnknownRecord, "Couldn't find #{self.name} with ID=#{id}")
end

.recordsObject



19
20
21
# File 'lib/supermodel/base.rb', line 19

def records
  @records ||= {}
end

.select(&block) ⇒ Object



66
67
68
# File 'lib/supermodel/base.rb', line 66

def select(&block)
  collection.new(records.values.select(&block).deep_dup)
end

.update(id, atts) ⇒ Object



70
71
72
# File 'lib/supermodel/base.rb', line 70

def update(id, atts)
  find(id).update_attributes(atts)
end

Instance Method Details

#==(other) ⇒ Object



158
159
160
# File 'lib/supermodel/base.rb', line 158

def ==(other)
  other.equal?(self) || (other.instance_of?(self.class) && other.id == id)
end

#cloneObject



134
135
136
137
138
139
140
141
# File 'lib/supermodel/base.rb', line 134

def clone
  cloned = attributes.reject {|k,v| k == self.class.primary_key }
  cloned = cloned.inject({}) do |attrs, (k, v)|
    attrs[k] = v.clone
    attrs
  end
  self.class.new(cloned)
end

#destroyObject



237
238
239
240
# File 'lib/supermodel/base.rb', line 237

def destroy
  raw_destroy
  self
end

#dupObject



171
172
173
174
175
176
# File 'lib/supermodel/base.rb', line 171

def dup
  self.class.new.tap do |base|
    base.attributes = attributes
    base.new_record = new_record?
  end
end

#eql?(other) ⇒ Boolean

Tests for equality (delegates to ==).

Returns:

  • (Boolean)


163
164
165
# File 'lib/supermodel/base.rb', line 163

def eql?(other)
  self == other
end

#exists?Boolean Also known as: persisted?

Returns:

  • (Boolean)


186
187
188
# File 'lib/supermodel/base.rb', line 186

def exists?
  !new?
end

#has_attribute?(name) ⇒ Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/supermodel/base.rb', line 218

def has_attribute?(name)
  @attributes.has_key?(name)
end

#hashObject



167
168
169
# File 'lib/supermodel/base.rb', line 167

def hash
  id.hash
end

#idObject

Gets the \id attribute of the item.



149
150
151
# File 'lib/supermodel/base.rb', line 149

def id
  attributes[self.class.primary_key]
end

#id=(id) ⇒ Object

Sets the \id attribute of the item.



154
155
156
# File 'lib/supermodel/base.rb', line 154

def id=(id)
  attributes[self.class.primary_key] = id
end

#known_attributesObject



122
123
124
# File 'lib/supermodel/base.rb', line 122

def known_attributes
  self.class.known_attributes + self.attributes.keys.map(&:to_s)
end

#load(attributes) ⇒ Object

:nodoc:



191
192
193
194
195
196
# File 'lib/supermodel/base.rb', line 191

def load(attributes) #:nodoc:
  return unless attributes
  attributes.each do |(name, value)| 
    self.send("#{name}=".to_sym, value) 
  end
end

#new?Boolean Also known as: new_record?

Returns:

  • (Boolean)


143
144
145
# File 'lib/supermodel/base.rb', line 143

def new?
  @new_record || false
end

#reloadObject



198
199
200
201
202
203
# File 'lib/supermodel/base.rb', line 198

def reload
  return self if new?
  item = self.class.find(id)
  load(item.attributes)
  return self
end

#respond_to?(method, include_priv = false) ⇒ Boolean

Returns:

  • (Boolean)


224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/supermodel/base.rb', line 224

def respond_to?(method, include_priv = false)
  method_name = method.to_s
  if attributes.nil?
    super
  elsif known_attributes.include?(method_name)
    true
  elsif method_name =~ /(?:=|\?)$/ && attributes.include?($`)
    true
  else
    super
  end
end

#respond_to_without_attributes?Object



222
# File 'lib/supermodel/base.rb', line 222

alias_method :respond_to_without_attributes?, :respond_to?

#saveObject



178
179
180
# File 'lib/supermodel/base.rb', line 178

def save
  new? ? create : update
end

#save!Object



182
183
184
# File 'lib/supermodel/base.rb', line 182

def save!
  save || raise(InvalidRecord)
end

#update_attribute(name, value) ⇒ Object



205
206
207
208
# File 'lib/supermodel/base.rb', line 205

def update_attribute(name, value)
  self.send("#{name}=".to_sym, value)
  self.save
end

#update_attributes(attributes) ⇒ Object



210
211
212
# File 'lib/supermodel/base.rb', line 210

def update_attributes(attributes)
  load(attributes) && save
end

#update_attributes!(attributes) ⇒ Object



214
215
216
# File 'lib/supermodel/base.rb', line 214

def update_attributes!(attributes)
  update_attributes(attributes) || raise(InvalidRecord)
end