Module: Platanus::ModelShims::ClassMethods

Defined in:
lib/platanus/model_shims.rb

Instance Method Summary collapse

Instance Method Details

#shims_for(_name, _options = {}) ⇒ Object

Generate shims for a given model.

  • class_name: if given, the shims model class name, if no the camelize _name is used.

  • prefix: prefix to be used in shims, defaults to ”.

  • proxy: an attribute to be proxied, if given then getter shims will return the proxie’s

value for the property if not set.

  • sync_to: same as proxy, but also call proxy_will_change! if any shimmed attribute is set.



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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/platanus/model_shims.rb', line 32

def shims_for(_name, _options={})

  # TODO: detect if _name is an association and use the association's settings.
  # TODO: overriding options.

  name = _name.to_s
  model = _options.fetch(:class_name, name.camelize).constantize
  cache_var = _options.fetch :into, "@_#{name}_shims"
  prefix = _options[:prefix]
  sync_to = _options[:sync_to]
  sync_to_fk = self.reflections[sync_to.to_sym].foreign_key if sync_to
  proxy = _options.fetch :proxy, sync_to

  model.accessible_attributes.each do |attr_name|

    full_attr_name = if prefix then "#{prefix}#{attr_name}" else attr_name end

    if method_defined? full_attr_name
      Rails.logger.warn "shims_for: overriding getter for #{full_attr_name} in #{self.to_s}"
    end

    if method_defined? "#{full_attr_name}="
      Rails.logger.warn "shims_for: overriding setter for #{full_attr_name} in #{self.to_s}"
    end

    # override getter
    define_method full_attr_name do
      cache = instance_variable_get(cache_var)
      return cache[attr_name] if cache and cache.has_key? attr_name
      if proxy
        child = send(proxy)
        if child then child.send(attr_name) else nil end
      end
    end

    # override setter
    define_method "#{full_attr_name}=" do |value|
      cache = instance_variable_get(cache_var)
      cache = instance_variable_set(cache_var, {}) if cache.nil?
      cache[attr_name] = value
      send "#{sync_to_fk}_will_change!" if sync_to # force update if synced
    end
    attr_accessible full_attr_name

  end

  define_method("#{name}_shims_changed?") do
    not instance_variable_get(cache_var).nil?
  end

  define_method("#{name}_shims_flush") do
    cache = instance_variable_get(cache_var)
    instance_variable_set(cache_var, nil)
    return cache
  end
end