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

Class Attribute Summary collapse

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.



130
131
132
133
134
135
136
# File 'lib/supermodel/base.rb', line 130

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:



286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/supermodel/base.rb', line 286

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

Class Attribute Details

.primary_keyObject

:nodoc:



7
8
9
# File 'lib/supermodel/base.rb', line 7

def primary_key
  @primary_key
end

Instance Attribute Details

#attributesObject

Returns the value of attribute attributes.



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

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.



124
125
126
# File 'lib/supermodel/base.rb', line 124

def new_record=(value)
  @new_record = value
end

Class Method Details

.allObject



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

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

.attributes(*attributes) ⇒ Object



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

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

.collection(&block) ⇒ Object



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

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

.countObject



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

def count
  records.length
end

.create(atts = {}) ⇒ Object

Create a new record. Example:

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


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

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

.create!(*args) ⇒ Object



102
103
104
# File 'lib/supermodel/base.rb', line 102

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

.delete_allObject

Removes all records without executing destroy callbacks.



90
91
92
# File 'lib/supermodel/base.rb', line 90

def delete_all
  records.clear
end

.destroy(id) ⇒ Object



78
79
80
# File 'lib/supermodel/base.rb', line 78

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

.destroy_allObject

Removes all records and executes destory callbacks.



84
85
86
# File 'lib/supermodel/base.rb', line 84

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

.exists?(id) ⇒ Boolean

Returns:

  • (Boolean)


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

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

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

Find record by ID, or raise.



42
43
44
45
# File 'lib/supermodel/base.rb', line 42

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

.find_all_by_attribute(name, value) ⇒ Object

:nodoc:



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

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:



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

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

.firstObject



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

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

.lastObject



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

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

.method_missing(method_symbol, *args) ⇒ Object

:nodoc:



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/supermodel/base.rb', line 106

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:



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

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

.recordsObject



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

def records
  @records ||= {}
end

.select(&block) ⇒ Object



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

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

.update(id, atts) ⇒ Object



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

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

Instance Method Details

#==(other) ⇒ Object



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

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

#cloneObject



138
139
140
141
142
143
144
145
# File 'lib/supermodel/base.rb', line 138

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



241
242
243
244
# File 'lib/supermodel/base.rb', line 241

def destroy
  raw_destroy
  self
end

#dupObject



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

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)


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

def eql?(other)
  self == other
end

#exists?Boolean Also known as: persisted?

Returns:

  • (Boolean)


190
191
192
# File 'lib/supermodel/base.rb', line 190

def exists?
  !new?
end

#has_attribute?(name) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#hashObject



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

def hash
  id.hash
end

#idObject

Gets the \id attribute of the item.



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

def id
  attributes[self.class.primary_key]
end

#id=(id) ⇒ Object

Sets the \id attribute of the item.



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

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

#known_attributesObject



126
127
128
# File 'lib/supermodel/base.rb', line 126

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

#load(attributes) ⇒ Object

:nodoc:



195
196
197
198
199
200
# File 'lib/supermodel/base.rb', line 195

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)


147
148
149
# File 'lib/supermodel/base.rb', line 147

def new?
  @new_record || false
end

#reloadObject



202
203
204
205
206
207
# File 'lib/supermodel/base.rb', line 202

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)


228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/supermodel/base.rb', line 228

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



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

alias_method :respond_to_without_attributes?, :respond_to?

#saveObject



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

def save
  new? ? create : update
end

#save!Object



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

def save!
  save || raise(InvalidRecord)
end

#update_attribute(name, value) ⇒ Object



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

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

#update_attributes(attributes) ⇒ Object



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

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

#update_attributes!(attributes) ⇒ Object



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

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