Class: ACH::Component
- Inherits:
-
Object
- Object
- ACH::Component
- Extended by:
- ActiveSupport::Autoload
- Includes:
- Constants, Validations
- Defined in:
- lib/ach/component.rb
Overview
Base class for ACH::File and ACH::Batch. Every component has its own number of entities, header and control records. So it provides ACH::Component#header, ACH::Component#control, ACH::Component.has_many methods to manage them.
Example
class File < Component
has_many :batches
# implementation
end
Defined Under Namespace
Classes: HasManyAssociation, UnknownAttributeError
Constant Summary
Constants included from Constants
ACH::Constants::BATCH_ADDENDA_RECORD_TYPE, ACH::Constants::BATCH_CONTROL_RECORD_TYPE, ACH::Constants::BATCH_ENTRY_RECORD_TYPE, ACH::Constants::BATCH_HEADER_RECORD_TYPE, ACH::Constants::BLOCKING_FACTOR, ACH::Constants::FILE_CONTROL_RECORD_TYPE, ACH::Constants::FILE_HEADER_RECORD_TYPE, ACH::Constants::FORMAT_CODE, ACH::Constants::RECORD_SIZE, ACH::Constants::ROWS_DELIMITER
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
Class Method Summary collapse
-
.has_many(plural_name, options = {}) ⇒ Object
Creates a has_many association.
-
.inherited(klass) ⇒ Object
When inherited, clone class-related properties.
-
.method_missing(meth, *args) ⇒ Object
Uses
method_missing
pattern to specify default attributes for aComponent
.
Instance Method Summary collapse
-
#after_initialize ⇒ Object
Execute all
Proc
objects contained in theafter_initialize_hooks
array in the context of the object. -
#build_control(str) ⇒ ACH::Record::Base
Build a component-related
Control
record from a given string. -
#build_header(str) ⇒ ACH::Record::Base
Build a component (
File
orBatch
) relatedHeader
record from a given string. -
#control ⇒ ACH::Record::Base
Build a component-related
Control
record. -
#fields_for(klass) ⇒ Hash
Return a set of fields, that is a subset of
attributes
that can be used to initialize an instance of aklass
. -
#header(fields = {}) ⇒ Object
Sets header fields if fields or block passed.
-
#initialize(fields = {}) ⇒ Component
constructor
Initialize component with field values.
-
#method_missing(meth, *args) ⇒ String
Missing messages are treated as accessor methods for a component if their message name is defined by Formatter.
Methods included from Validations
Constructor Details
#initialize(fields = {}) ⇒ Component
Initialize component with field values. If block is given, it is evaluated in context of component, allowing setting fields via method calls and declarations of nested components.
73 74 75 76 77 78 79 80 81 |
# File 'lib/ach/component.rb', line 73 def initialize(fields = {}) @attributes = self.class.default_attributes.dup fields.each do |name, value| raise UnknownAttributeError.new(name, self) unless Formatter.defined?(name) @attributes[name] = value end after_initialize instance_eval(&Proc.new) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ String
Missing messages are treated as accessor methods for a component if their message name is defined by Formatter.
89 90 91 92 93 94 95 |
# File 'lib/ach/component.rb', line 89 def method_missing(meth, *args) if Formatter.defined?(meth) args.empty? ? @attributes[meth] : (@attributes[meth] = args.first) else super end end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
36 37 38 |
# File 'lib/ach/component.rb', line 36 def attributes @attributes end |
Class Method Details
.has_many(plural_name, options = {}) ⇒ Object
Creates a has_many association.
Example
class File < Component
has_many :batches
end
file = File.new do
batch :foo => 1, :bar => 2
end
file.batches # => [#<Batch ...>]
The example above extends File with #batches and #batch instance methods:
-
#batch is used to add new instance of Batch.
-
#batches is used to get an array of batches which belong to file.
195 196 197 198 199 200 201 202 203 204 |
# File 'lib/ach/component.rb', line 195 def self.has_many(plural_name, = {}) association = HasManyAssociation.new(plural_name, ) association_variable_name = "@#{plural_name}_association" association.delegation_methods.each do |method_name| delegate method_name, :to => association_variable_name end after_initialize_hooks << lambda{ instance_variable_set(association_variable_name, association.for(self)) } end |
.inherited(klass) ⇒ Object
When inherited, clone class-related properties.
41 42 43 44 |
# File 'lib/ach/component.rb', line 41 def self.inherited(klass) klass.default_attributes = default_attributes.dup klass.after_initialize_hooks = after_initialize_hooks.dup end |
.method_missing(meth, *args) ⇒ Object
Uses method_missing
pattern to specify default attributes for a Component
. If method name is one of the defined rules, saves it to default_attributes
hash.
These attributes are passed to inner components in a cascade way, i.e. when ACH File was defined with default value for ‘company_name’, this value will be passed to every Batch component within file, and from every Batch to corresponding batch header record.
Note that default values may be overwritten when building records.
59 60 61 62 63 64 65 |
# File 'lib/ach/component.rb', line 59 def self.method_missing(meth, *args) if Formatter.defined?(meth) default_attributes[meth] = args.first else super end end |
Instance Method Details
#after_initialize ⇒ Object
Execute all Proc
objects contained in the after_initialize_hooks
array in the context of the object.
171 172 173 |
# File 'lib/ach/component.rb', line 171 def after_initialize self.class.after_initialize_hooks.each{ |hook| instance_exec(&hook) } end |
#build_control(str) ⇒ ACH::Record::Base
Build a component-related Control
record from a given string.
151 152 153 |
# File 'lib/ach/component.rb', line 151 def build_control(str) @control = self.class::Control.from_s(str) end |
#build_header(str) ⇒ ACH::Record::Base
Build a component (File
or Batch
) related Header
record from a given string.
132 133 134 |
# File 'lib/ach/component.rb', line 132 def build_header(str) @header = self.class::Header.from_s(str) end |
#control ⇒ ACH::Record::Base
Build a component-related Control
record.
139 140 141 142 143 144 145 |
# File 'lib/ach/component.rb', line 139 def control @control ||= begin klass = self.class::Control fields = klass.fields.select{ |f| respond_to?(f) || attributes[f] } klass.new Hash[*fields.zip(fields.map{ |f| send(f) }).flatten] end end |
#fields_for(klass) ⇒ Hash
Return a set of fields, that is a subset of attributes
that can be used to initialize an instance of a klass
. Component
uses attributes
itself.
160 161 162 163 164 165 166 167 |
# File 'lib/ach/component.rb', line 160 def fields_for(klass) if klass < Component attributes else attrs = attributes.find_all{ |k, v| klass.fields.include?(k) && attributes[k] } Hash[*attrs.flatten] end end |
#header(fields = {}) ⇒ Object
Sets header fields if fields or block passed. Returns header record.
Example 1
header :foo => "value 1", :bar => "value 2"
Example 2
header do
foo "value 1"
"value 2"
end
Example 3
header # => just returns a header object
119 120 121 122 123 124 125 126 |
# File 'lib/ach/component.rb', line 119 def header(fields = {}) before_header merged_fields = fields_for(self.class::Header).merge(fields) @header ||= self.class::Header.new(merged_fields) @header.tap do |head| head.instance_eval(&Proc.new) if block_given? end end |