Class: NinjaModel::Base

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Callbacks, ActiveModel::Naming, ActiveModel::Translation
Includes:
ActiveModel::AttributeMethods, ActiveModel::Dirty, ActiveModel::Observing, ActiveModel::Serializers::JSON, ActiveModel::Serializers::Xml, ActiveModel::Validations, ActiveRecord::Aggregations, ActiveRecord::NamedScope, Adapters, Associations, AttributeMethods, Identity, Persistence, Reflection, Validation
Defined in:
lib/ninja_model.rb,
lib/ninja_model/base.rb,
lib/ninja_model/adapters.rb,
lib/ninja_model/identity.rb,
lib/ninja_model/callbacks.rb,
lib/ninja_model/reflection.rb,
lib/ninja_model/validation.rb,
lib/ninja_model/persistence.rb,
lib/ninja_model/associations.rb,
lib/ninja_model/attribute_methods.rb,
lib/ninja_model/rails_ext/active_record.rb

Defined Under Namespace

Classes: UnknownAttributeError

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Associations

#association_instance_get, #association_instance_set

Methods included from Validation

#save, #valid?

Methods included from Persistence

#create, #destroy, #destroyed?, #new_record?, #persisted?, #reload, #save, #update, #update_attributes

Methods included from Identity

#to_key, #to_model, #to_param

Methods included from AttributeMethods

#[], #[]=, #attribute_method?, #attributes=, #attributes_from_model_attributes, #read_attribute, #write_attribute

Constructor Details

#initialize(attributes = nil) ⇒ Base

Returns a new instance of Base.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ninja_model/base.rb', line 91

def initialize(attributes = nil)
  @attributes = attributes_from_model_attributes
  @persisted = false
  @readonly = true
  @destroyed = false

  populate_with_current_scope_attributes

  self.attributes = attributes unless attributes.nil?

  result = yield self if block_given?
  _run_initialize_callbacks
  result
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/ninja_model/rails_ext/active_record.rb', line 92

def method_missing(method, *args)
  if self.class.read_inheritable_attribute(:proxy) && proxy.respond_to?(method)
    proxy.send(method, *args)
  else
    super
  end
end

Class Method Details

.attribute(name, data_type, *args) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/ninja_model/attribute_methods.rb', line 13

def attribute(name, data_type, *args)
  name = name.to_s
  opts = args.extract_options!
  primary = opts.delete(:primary_key)
  self.primary_key = name if primary.eql?(true)
  default = args.first unless args.blank?
  new_attr = Attribute.new(name, data_type, opts)
  self.model_attributes << new_attr
  define_attribute_methods(true)
end

.attribute_namesObject Also known as: column_names



40
41
42
# File 'lib/ninja_model/attribute_methods.rb', line 40

def attribute_names
  @attribute_names ||= model_attributes.map { |attribute| attribute.name }
end

.belongs_to(association_id, options = {}) ⇒ Object



14
15
16
17
18
19
20
# File 'lib/ninja_model/associations.rb', line 14

def belongs_to(association_id, options = {})
  reflection = create_belongs_to_reflection(association_id, options)
  association_accessor_methods(reflection, Associations::BelongsToAssociation)
  # TODO: Implement the build/create association methods
  #association_constructor_method(:build, reflection, BelongsToAssociation)
  #association_constructor_method(:create, reflection, BelongsToAssociation)
end

.belongs_to_with_active_record(association_id, options = {}) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/ninja_model/rails_ext/active_record.rb', line 59

def belongs_to_with_active_record(association_id, options = {})
  if ninja_model?(:belongs_to, options[:class_name] || association_id)
    belongs_to_without_active_record(association_id, options)
  else
    proxy.handle_association(:belongs_to, association_id, options)
  end
end

.columnsObject



30
31
32
# File 'lib/ninja_model/attribute_methods.rb', line 30

def columns
  model_attributes
end

.create_reflection(macro, name, options, ninja_model) ⇒ Object



4
5
6
7
8
9
10
11
# File 'lib/ninja_model/reflection.rb', line 4

def create_reflection(macro, name, options, ninja_model)
  case macro
  when :has_many, :belongs_to, :has_one
    reflection = Reflection::AssociationReflection.new(macro, name, options, ninja_model)
  end
  write_inheritable_hash :reflections, name => reflection
  reflection
end

.current_scoped_methodsObject



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

def current_scoped_methods
  last = scoped_methods.last
  last.is_a?(Proc) ? unscoped(&last) : last
end

.default_scope(options = {}) ⇒ Object



60
61
62
63
# File 'lib/ninja_model/base.rb', line 60

def default_scope(options = {})
  reset_scoped_methods
  self.default_scoping << build_finder_relation(options, default_scoping.pop)
end

.define_attribute_methods(force = false) ⇒ Object



24
25
26
27
28
# File 'lib/ninja_model/attribute_methods.rb', line 24

def define_attribute_methods(force = false)
  return unless self.model_attributes
  undefine_attribute_methods if force
  super(self.model_attributes.map { |attr| attr.name })
end

.has_many(association_id, options = {}) ⇒ Object



22
23
24
25
# File 'lib/ninja_model/associations.rb', line 22

def has_many(association_id, options = {})
  reflection = create_has_many_reflection(association_id, options)
  collection_accessor_methods(reflection, Associations::HasManyAssociation)
end

.has_many_with_active_record(association_id, options = {}) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/ninja_model/rails_ext/active_record.rb', line 69

def has_many_with_active_record(association_id, options = {})
  if ninja_model?(:has_many, association_id)
    has_many_without_active_record(association_id, options)
  else
    proxy.handle_association(:has_many, association_id, options)
  end
end

.has_one(association_id, options = {}) ⇒ Object



5
6
7
8
9
10
11
12
# File 'lib/ninja_model/associations.rb', line 5

def has_one(association_id, options = {})
  reflection = create_has_one_reflection(association_id, options)
  association_accessor_methods(reflection, Associations::HasOneAssociation)
  # TODO: Implement the build/create association methods
  #association_constructor_method(:build, reflection, HasOneAssociation)
  #association_constructor_method(:create, reflection, HasOneAssociation)
  #configure_dependency_for_has_one(reflection)
end

.has_one_with_active_record(association_id, options = {}) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/ninja_model/rails_ext/active_record.rb', line 49

def has_one_with_active_record(association_id, options = {})
  if ninja_model?(:has_one, options[:class_name] || association_id)
    has_one_without_active_record(association_id, options)
  else
    proxy.handle_association(:has_one, association_id, options)
  end
end

.loggerObject



47
48
49
# File 'lib/ninja_model/base.rb', line 47

def logger
  ::NinjaModel.logger
end

.model_attributes_hashObject Also known as: columns_hash



34
35
36
# File 'lib/ninja_model/attribute_methods.rb', line 34

def model_attributes_hash
  @attributes_hash ||= HashWithIndifferentAccess[model_attributes.map { |attribute| [attribute.name, attribute] }]
end

.ninja_model?(macro, association) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
16
17
18
# File 'lib/ninja_model/reflection.rb', line 13

def ninja_model?(macro, association)
  klass = association.to_s.camelize
  klass = klass.singularize unless [:has_one, :belongs_to].include?(macro)
  klass = klass.constantize
  defined?(klass) && klass.ancestors.include?(NinjaModel::Base)
end

.proxyObject



79
80
81
# File 'lib/ninja_model/rails_ext/active_record.rb', line 79

def proxy
  read_inheritable_attribute(:proxy) || write_inheritable_attribute(:proxy, Associations::ActiveRecordProxy.new(self))
end

.reflect_on_association(association) ⇒ Object



24
25
26
# File 'lib/ninja_model/reflection.rb', line 24

def reflect_on_association(association)
  reflections[association].is_a?(Reflection::AssociationReflection) ? reflections[association] : nil
end

.reflectionsObject



20
21
22
# File 'lib/ninja_model/reflection.rb', line 20

def reflections
  read_inheritable_attribute(:reflections) || write_inheritable_attribute(:reflections, {})
end

.register_adapter(name, klass) ⇒ Object



23
24
25
# File 'lib/ninja_model/adapters.rb', line 23

def register_adapter(name, klass)
  Adapters::AdapterManager.register_adapter_class(name, klass)
end

.relationObject



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

def relation
  @relation ||= Relation.new(self)
end

.reset_scoped_methodsObject



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

def reset_scoped_methods
  Thread.current["#{self}_scoped_methods".to_sym] = nil
end

.retrieve_adapterObject Also known as: adapter



50
51
52
# File 'lib/ninja_model/adapters.rb', line 50

def retrieve_adapter
  adapter_manager.retrieve_adapter(self)
end

.scoped_methodsObject



55
56
57
58
# File 'lib/ninja_model/base.rb', line 55

def scoped_methods
  key = "#{self}_scoped_methods".to_sym
  Thread.current[key] = Thread.current[key].presence || self.default_scoping.dup
end

.set_adapter(spec = nil) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ninja_model/adapters.rb', line 27

def set_adapter(spec = nil)
  case spec
  when nil
    raise Adapters::AdapterNotSpecified unless defined?(Rails.env)
    set_adapter(Rails.env)
  when Adapters::AdapterSpecification
    self.adapter_manager.create_adapter(name, spec)
  when Symbol, String
    if config = NinjaModel.configuration.specs[spec.to_s]
      set_adapter(config)
    else
      raise Adapters::InvalidSpecification, "#{spec} is not configured"
    end
  else
    spec = spec.symbolize_keys
    raise Adapters::AdapterNotSpecified, "configuration does not specify adapter" unless spec.key?(:adapter)
    adapter_name = spec[:adapter]
    raise Adapters::InvalidAdapter, "configuration does not specify adapter" unless Adapters::AdapterManager.registered?(adapter_name)
    shutdown_adapter
    set_adapter(Adapters::AdapterSpecification.new(spec, adapter_name))
  end
end

.shutdown_adapter(klass = self) ⇒ Object



55
56
57
# File 'lib/ninja_model/adapters.rb', line 55

def shutdown_adapter(klass = self)
  adapter_manager.remove_adapter(klass)
end

.unscopedObject



51
52
53
# File 'lib/ninja_model/base.rb', line 51

def unscoped
  block_given? ? relation.scoping { yield } : relation
end

Instance Method Details

#adapterObject



18
19
20
# File 'lib/ninja_model/adapters.rb', line 18

def adapter
  self.class.retrieve_adapter
end

#attributesObject



83
84
85
86
87
88
89
# File 'lib/ninja_model/base.rb', line 83

def attributes
  attrs = {}
  self.class.attribute_names.each { |name|
    attrs[name] = read_attribute(name)
  }
  attrs
end

#instantiate(record) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/ninja_model/base.rb', line 106

def instantiate(record)
  @attributes = record.stringify_keys
  @readonly = @destroyed = false
  @persisted = true

  populate_with_current_scope_attributes

  _run_find_callbacks
  _run_initialize_callbacks
  self
end

#respond_to?(sym) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
# File 'lib/ninja_model/rails_ext/active_record.rb', line 84

def respond_to?(sym)
  if self.class.read_inheritable_attribute(:proxy) && proxy.respond_to?(sym)
    true
  else
    super
  end
end