Module: PortableModel

Defined in:
lib/portable_model.rb,
lib/portable_model/version.rb

Overview

Include PortableModel in any ActiveRecord model to enable exporting and importing the model’s records.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

VERSION =
"1.3.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#importing_recordObject

This virtual attribute is now deprecated in favor of #currently_importing?



15
16
17
# File 'lib/portable_model.rb', line 15

def importing_record
  @importing_record
end

Class Method Details

.included(base) ⇒ Object



9
10
11
# File 'lib/portable_model.rb', line 9

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#currently_importing?Boolean

Check whether the record is currently being imported. Callers can use this for determining when to skip callbacks and validations that shouldn’t be run when a record is being imported.

Returns:

  • (Boolean)


21
22
23
# File 'lib/portable_model.rb', line 21

def currently_importing?
  !!Thread.current[:imported_records]
end

#export_from_association(assoc_name) ⇒ Object

Export values from the record’s association.



76
77
78
# File 'lib/portable_model.rb', line 76

def export_from_association(assoc_name)
  self.__send__(assoc_name).export_portable_association
end

#export_to_hashObject

Export the record to a hash.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/portable_model.rb', line 27

def export_to_hash
  self.class.start_exporting do |exported_records|
    # If the record had already been exported during the current session, use
    # the result of that previous export.
    record_id = "#{self.class.table_name}_#{id}"
    record_hash = exported_records[record_id]

    unless record_hash
      # Export portable attributes.
      record_hash = self.class.portable_attributes.inject({}) do |hash, attr_name|
        hash[attr_name] = if self.class.overridden_export_attrs.has_key?(attr_name)
                            overridden_value = self.class.overridden_export_attrs[attr_name]
                            overridden_value.is_a?(Proc) ? instance_eval(&overridden_value) : overridden_value
                          else
                            attributes[attr_name]
                          end
        hash
      end

      # Include the exported attributes of portable associations.
      self.class.portable_associations.inject(record_hash) do |hash, assoc_name|
        assoc = self.__send__(assoc_name)
        if assoc
           if assoc.respond_to?(:export_portable_association)
             hash[assoc_name] = assoc.export_portable_association
           elsif !assoc.new_record?
             hash[assoc_name] = assoc.export_to_hash
           end
        end
        hash
      end

      exported_records[record_id] = record_hash
    end

    record_hash
  end
end

#export_to_yml(filename) ⇒ Object

Export the record to a YAML file.



68
69
70
71
72
# File 'lib/portable_model.rb', line 68

def export_to_yml(filename)
  Pathname.new(filename).open('w') do |out|
    YAML::dump(export_to_hash, out)
  end
end

#import_into_association(assoc_name, assoc_value, options = {}) ⇒ Object

Import values into the record’s association.



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/portable_model.rb', line 82

def import_into_association(assoc_name, assoc_value, options = {})
  assoc = self.__send__(assoc_name)
  if assoc
    assoc.import_portable_association(assoc_value, options)
  else
    assoc_reflection = self.class.reflect_on_association(assoc_name.to_sym)
    raise 'nil can only be handled for direct has_one associations' unless assoc_reflection.macro == :has_one && !assoc_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
    assoc = ActiveRecord::Associations::HasOneAssociation.new(self, assoc_reflection)
    assoc.import_portable_association(assoc_value, options)
    association_instance_set(assoc_reflection.name, assoc.target.nil? ? nil : assoc)
  end
end