Module: Detailed

Defined in:
lib/detailed.rb

Defined Under Namespace

Modules: AssociationScope

Class Method Summary collapse

Class Method Details

.included(mod) ⇒ Object



25
26
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/detailed.rb', line 25

def self.included (mod)
  class << mod
    attr_accessor :subclasses
    
    def add_subclass(sc)
      @subclasses ||= []
      @subclasses << sc
      
      class_eval do
        has_one :"details_of_#{sc.name.tableize}", class_name: "#{self.name}#{sc.name}Detail", foreign_key: "#{sc.name.tableize.singularize}_id", autosave: true #, inverse_of: "#{sc.name.tableize}"
      end
    end
    
    def all_with_details
      @subclasses ||= []
      @subclasses.inject(self.unscoped) { |a,b| a.includes(:"details_of_#{b.name.tableize}") }
    end
    
    def request_details
      self.superclass.add_subclass(self)
      
  class_eval do
 accepts_nested_attributes_for :"details_of_#{self.name.tableize}"
        default_scope do
          eager_load :"details_of_#{self.name.tableize}"
        end
        
        alias :details  :"details_of_#{self.name.tableize}"
        alias :details= :"details_of_#{self.name.tableize}="
 
 after_initialize do
   self.details ||= "#{self.class.superclass.name}#{self.class.name}Detail".constantize.new if self.new_record?
 end
 
 alias :__old_method_missing :method_missing
 alias :__old_respond_to? :respond_to?
 alias :__old_methods :methods
        alias :__old_write_attribute :write_attribute
        alias :__old_read_attribute :read_attribute
        alias :__old_query_attribute :query_attribute
        
        def query_attribute a
          __old_query_attribute(a) or (details and details.send(:query_attribute, a))
        end
        
        def read_attribute a
          __old_read_attribute(a) or (details and details.send(:read_attribute, a))
        end
        
        def write_attribute a, b
          __old_write_attribute a, b
        rescue ActiveModel::MissingAttributeError => e
          begin
            details.send :write_attribute, a, b
          rescue ActiveModel::MissingAttributeError
            raise e
          end
        end

 def method_missing a, *b
          __old_method_missing a, *b
        rescue NoMethodError, NameError => e
   begin
            details.send a, *b
          rescue NoMethodError, NameError
            raise e
          end
 end
 
 def respond_to? *a
   __old_respond_to?(*a) or (details ? details.respond_to?(*a) : false)
 end
 
 def methods *a
   __old_methods(*a) | (details ? details.methods(*a) : [])
 end
  end
    end
  end
end