Module: Detailed

Defined in:
lib/detailed.rb

Defined Under Namespace

Modules: AssociationScope

Class Method Summary collapse

Class Method Details

.included(mod) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
# File 'lib/detailed.rb', line 4

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" #, 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