Module: SimpleModel::Attributes::ClassMethods

Defined in:
lib/simple_model/attributes.rb

Constant Summary collapse

DEFAULT_ATTRIBUTE_SETTINGS =
{:attributes_method => :attributes,
:allow_blank => true,
:initialize => true
}.freeze
AVAILABLE_ATTRIBUTE_METHODS =
{
  :has_attribute => {:alias => :has_attributes},
  :has_boolean  => {:cast_to => :to_b, :alias => :has_booleans},
  :has_currency => {:cast_to => :to_d, :alias => :has_currencies},
  :has_date => {:cast_to => :to_date, :alias => :has_dates} ,
  :has_decimal  => {:cast_to => :to_d, :alias => :has_decimals},
  :has_float => {:cast_to => :to_f, :alias => :has_floats},
  :has_int => {:cast_to => :to_i, :alias => :has_ints},
  :has_time => {:cast_to => :to_time, :alias => :has_times}
}.freeze

Instance Method Summary collapse

Instance Method Details

#add_defined_attribute(attr, options) ⇒ Object

We want to re-run define_attribute_methods since attributes are not all defined at once, so we must set @attribute_methods_generated to nil to allow the re-run to occur ONLY IN RAILS 3.0.



215
216
217
218
219
# File 'lib/simple_model/attributes.rb', line 215

def add_defined_attribute(attr,options)
  self.defined_attributes[attr] = options
  @attribute_methods_generated = nil #if (ActiveModel::VERSION::MAJOR == 3 && ActiveModel::VERSION::MINOR == 0)
  define_attribute_methods(defined_attributes_keys)
end

#after_initializeObject

A hook to perform actions after all attributes have been initialized Expects an lambda that accept the object and the pending attributes hash EX: lambda {|obj| puts “initialized”}



292
293
294
# File 'lib/simple_model/attributes.rb', line 292

def after_initialize
  @after_initialize
end

#after_initialize=(after_initialize) ⇒ Object

Expects an lambda that accept the object and the pending attributes hash EX: lambda {|obj| puts “initialized”}



298
299
300
301
# File 'lib/simple_model/attributes.rb', line 298

def after_initialize=after_initialize
  raise TypeError "after_initalize must be a Proc" unless after_initialize.is_a?(Proc)
  @after_initialize = after_initialize
end

#alias_attribute(new_alias, attribute) ⇒ Object

Creates alias setter and getter for the supplied attribute using the supplied alias See spec for example.



259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/simple_model/attributes.rb', line 259

def alias_attribute(new_alias,attribute)
  alias_attributes[attribute] = new_alias
  define_method(new_alias) do
    self.send(attribute)
  end
  define_method("#{new_alias}?") do
    self.send("#{attribute}?")
  end
  define_method("#{new_alias.to_s}=") do |*args, &block|
    self.send("#{attribute.to_s}=",*args, &block)
  end
end

#alias_attributesObject



176
177
178
# File 'lib/simple_model/attributes.rb', line 176

def alias_attributes
  @alias_attributes ||= HashWithIndifferentAccess.new
end

#alias_attributes=(alias_attributes) ⇒ Object



180
181
182
# File 'lib/simple_model/attributes.rb', line 180

def alias_attributes=alias_attributes
  @alias_attributes = alias_attributes
end

#attribute_defined?(attr) ⇒ Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/simple_model/attributes.rb', line 192

def attribute_defined?(attr)
  (self.defined_attributes.member?(attr) || self.superclass.respond_to?(:attribute_defined?) && self.superclass.attribute_defined?(attr))
end

#before_initializeObject

A hook to perform actions on the pending attributes or the object before the pending attributes have been initialized. Expects an lambda that accept the object, the pending attributes hash and should return a hash to be set EX: lambda {|obj,attrs| attrs.select{|k,v| !v.blank?}}



277
278
279
# File 'lib/simple_model/attributes.rb', line 277

def before_initialize
  @before_initialize
end

#before_initialize=(before_initialize) ⇒ Object

Expects an lambda that accept the object, the pending attributes hash and should return a hash to be set EX: lambda {|obj,attrs| attrs.select{|k,v| !v.blank?}}



284
285
286
287
# File 'lib/simple_model/attributes.rb', line 284

def before_initialize=before_initialize
  raise TypeError "before_initialize must be a lambda that accepts the attirbutes to be initialize" unless before_initialize.is_a?(Proc)
  @before_initialize = before_initialize
end

#create_attribute_methods(attributes, options) ⇒ Object

builds the setter and getter methods



229
230
231
232
233
234
235
236
237
# File 'lib/simple_model/attributes.rb', line 229

def create_attribute_methods(attributes,options)
  unless attributes.blank?
    attributes.each do |attr|
      define_setter_with_options(attr,options)
      define_reader_with_options(attr,options)
      add_defined_attribute(attr,options)
    end
  end
end

#default_attribute_settingsObject

The default settings for a SimpeModel class Options:

  • :on_set - accepts a lambda that is run when an attribute is set

  • :on_get - accepts a lambda that is run when you get/read an attribute

  • :default - the default value for the attribute, can be a symbol that is sent for a method

  • :initialize - informations the object whether or not it should initialize the attribute with :default value, defaults to true

** If :initialize is set to false you must set :allow_blank to false or it will never set the default value

  • :allow_blank - when set to false, if an attributes value is blank attempts to set the default value, defaults to true



204
205
206
# File 'lib/simple_model/attributes.rb', line 204

def default_attribute_settings
  @default_attribute_settings ||= DEFAULT_ATTRIBUTE_SETTINGS
end

#default_attribute_settings=(default_attribute_settings) ⇒ Object



208
209
210
# File 'lib/simple_model/attributes.rb', line 208

def default_attribute_settings=default_attribute_settings
  @default_attribute_settings = default_attribute_settings
end

#define_reader_with_options(attr, options) ⇒ Object



239
240
241
242
243
244
245
246
# File 'lib/simple_model/attributes.rb', line 239

def define_reader_with_options(attr,options)
  define_method(attr) do
    get_attribute(attr)
  end
  define_method("#{attr.to_s}?") do
    get_attribute?(attr)
  end
end

#define_setter_with_options(attr, options) ⇒ Object

Creates setter methods for the provided attributes On set, it will mark the attribute as changed if the attributes has been initialized.



251
252
253
254
255
# File 'lib/simple_model/attributes.rb', line 251

def define_setter_with_options(attr,options)
  define_method("#{attr.to_s}=") do |val|
    set_attribute(attr,val)
  end
end

#defined_attributesObject



184
185
186
# File 'lib/simple_model/attributes.rb', line 184

def defined_attributes
  @defined_attributes ||= HashWithIndifferentAccess.new
end

#defined_attributes=(defined_attributes) ⇒ Object



188
189
190
# File 'lib/simple_model/attributes.rb', line 188

def defined_attributes=defined_attributes
  @defined_attributes = defined_attributes
end

#defined_attributes_keysObject

We don’t want to call define_attribute_methods on methods defined in the parent class



222
223
224
225
226
# File 'lib/simple_model/attributes.rb', line 222

def defined_attributes_keys
  dak = self.defined_attributes.keys
  dak = dak - self.superclass.defined_attributes.keys if self.superclass.respond_to?(:defined_attributes)
  dak
end

#inherited(base) ⇒ Object

Must inherit super’s defined_attributes and alias_attributes Rails 3.0 does some weird stuff with ActiveModel::Dirty so we need a hack to keep things working when a class inherits from a super that has ActiveModel::Dirty included



307
308
309
310
311
312
313
314
315
316
# File 'lib/simple_model/attributes.rb', line 307

def inherited(base)
  base.defined_attributes = self.defined_attributes.dup
  base.alias_attributes = self.alias_attributes.dup
  super
  # Rails 3.0 Hack
  if (ActiveModel::VERSION::MAJOR == 3 && ActiveModel::VERSION::MINOR == 0)
    base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
    base.attribute_method_affix :prefix => 'reset_', :suffix => '!'
  end
end

#new_with_store(session_hash) ⇒ Object

Creates a new instance where the attributes store is set to object provided, which allows one to pass a session store hash or any other hash-like object to be used for persistence. Typically used for modeling session stores for authorization or shopping carts EX:

class ApplicationController < ActionController::Base
  def session_user
    session[:user] ||= {}
    @session_user ||= SessionUser.new_with_store(session[:user])
  end
  helper_method :session_user
end


169
170
171
172
173
174
# File 'lib/simple_model/attributes.rb', line 169

def new_with_store(session_hash)
  nw = self.new()
  nw.attributes = session_hash
  nw.set(nw.send(:attributes_with_for_init,session_hash))
  nw
end