class Poro::Context

This is the abstract superclass of all Contexts.

For find methods, see FindMethods.

The Context is the responsible delegate for directly interfacing with the persistence layer. Each program class that needs persistence must have its own context instance that knows how to store/retrive only instances of that class.

All instances respond to the methods declared here, and must conform to the rules described with each method.

One normally uses a subclass of Context, and that subclass may have extra methods for setting options and configuring behavior.

Attributes

data_store[RW]

The raw data store backing this context. This is useful for advanced usage, such as special queries. Be aware that whenever you use this, there is tight coupling with the underlying persistence store!

klass[R]

The class that this context instance services.

primary_key[R]

Returns the a symbol for the method that returns the Context assigned primary key for the managed object. This defaults to :id

Public Class Methods

configure_for_class(klass) { |context| ... } click to toggle source

A convenience method for further configuration of a context over what the factory does, via the passed block.

This really just fetches (and creates, if necessary) the Context for the class, and then yields it to the block. Returns the context.

# File lib/poro/context.rb, line 40
def self.configure_for_class(klass)
  context = self.fetch(klass)
  yield(context) if block_given?
  return context
end
factory() click to toggle source

Returns the application’s ContextFactory instance.

# File lib/poro/context.rb, line 47
def self.factory
  return ContextFactory.instance
end
factory=(context_factory) click to toggle source

Sets the application’s ContextFactory instance.

# File lib/poro/context.rb, line 52
def self.factory=(context_factory)
  ContextFactory.instance = context_factory
end
factory?() click to toggle source

Returns true if there is a factory assigned to the application.

# File lib/poro/context.rb, line 57
def self.factory?
  ContextFactory.has_instance?
end
fetch(obj) click to toggle source

Fetches the context for the given object or class from ContextFactory.instance. Returns nil if no context is found.

# File lib/poro/context.rb, line 21
def self.fetch(obj)
  if( obj.kind_of?(Class) )
    return self.factory.fetch(obj)
  else
    return self.factory.fetch(obj.class)
  end
end
managed_class?(klass) click to toggle source

Returns true if the given class is configured to be represented by a context. This is done by including Poro::Persistify into the module.

# File lib/poro/context.rb, line 31
def self.managed_class?(klass)
  return self.factory.context_managed_class?(klass)
end
new(klass) { |self| ... } click to toggle source

Initizialize this context for the given class. Yields self if a block is given, so that instances can be easily configured at instantiation.

Subclasses are expected to use this method (through calls to super).

# File lib/poro/context.rb, line 65
def initialize(klass)
  @klass = klass
  self.data_store = nil unless defined?(@data_store)
  self.primary_key = :id
  yield(self) if block_given?
end

Public Instance Methods

convert_to_data(obj, state_info={}) click to toggle source

Convert a plain ol’ ruby object into the data store data format this context represents.

For non-embedded persistent stores, only records of the type for this context must be handled. However, for embedded stores–or more complex embedded handling on non-embedded stores–more compex rules may be necessary, handling all sorts of data types.

The second argument is reserved for state information that the method may need to pass around, say if it is recursively converting elements. Any root object returned from a “find” in the data store needs to be able to be converted

# File lib/poro/context.rb, line 184
def convert_to_data(obj, state_info={})
  transformed_obj = callback_transform(:before_convert_to_data, obj)
  data = transformed_obj
  callback_event(:after_convert_to_data, data)
  return data
end
convert_to_plain_object(data, state_info={}) click to toggle source

Convert the data from the data store into the correct plain ol’ ruby object for the class this context represents.

For non-embedded persistent stores, only records of the type for this context must be handled. However, for embedded stores–or more complex embedded handling on non-embedded stores–more compex rules may be necessary, handling all sorts of data types.

The second argument is reserved for state information that the method may need to pass around, say if it is recursively converting elements. Any root object returned from a “find” in the data store needs to be able to be converted

# File lib/poro/context.rb, line 165
def convert_to_plain_object(data, state_info={})
  transformed_data = callback_transform(:before_convert_to_plain_object, data)
  obj = transformed_data
  callback_event(:after_convert_to_plain_object, obj)
  return obj
end
fetch(id) click to toggle source

Fetches the object from the store with the given id, or returns nil if there are none matching.

# File lib/poro/context.rb, line 113
def fetch(id)
  obj = convert_to_plain_object( clean_id(nil) )
  callback_event(:after_fetch, obj)
  return obj
end
primary_key=(pk) click to toggle source

Set the method that returns the Context assigned primary key for the managed object.

Note that if you want the primary key’s instance variable value to be purged from saved data, you must name the accessor the same as the instance method (like if using attr_reader and attr_writer).

# File lib/poro/context.rb, line 94
def primary_key=(pk)
  @primary_key = pk.to_sym
end
primary_key_value(obj) click to toggle source

Returns the primary key value from the given object, using the primary key set for this context.

# File lib/poro/context.rb, line 100
def primary_key_value(obj)
  return obj.send( primary_key() )
end
remove(obj) click to toggle source

Remove the given object from the persisten store using this context.

Subclasses do not need to call super, but should follow the given rules:

Returns the removed object.

If the object is successfully removed, the id is set to nil.

Raises an Error is the remove fails.

# File lib/poro/context.rb, line 146
def remove(obj)
  callback_event(:before_remove, obj)
  obj.id = nil if obj.respond_to?(:id=)
  callback_event(:after_remove, obj)
  return obj
end
save(obj) click to toggle source

Saves the given object to the persistent store using this context.

Subclasses do not need to call super, but should follow the given rules:

Returns the saved object.

If the object has never been saved, it should be inserted and given an id. If the object has been added before, the id is used to update the existing record.

Raises an Error if save fails.

# File lib/poro/context.rb, line 130
def save(obj)
  callback_event(:before_save, obj)
  obj.id = obj.object_id if obj.respond_to?(:id) && obj.id.nil? && obj.respond_to?(:id=)
  callback_event(:after_save, obj)
  return obj
end
set_primary_key_value(obj, id) click to toggle source

Sets the primary key value on the managed object, using the primary key set for this context.

# File lib/poro/context.rb, line 106
def set_primary_key_value(obj, id)
  method = (primary_key().to_s + '=').to_sym
  obj.send(method, id)
end

Private Instance Methods

clean_id(id) click to toggle source

Given a value that represents an ID, scrub it to produce a clean ID as is needed by the data store for the context.

This is used by methods like fetch and find_for_ids to convert the IDs from whatever types the user passed, into the correct values.

# File lib/poro/context.rb, line 199
def clean_id(id)
  return id
end