· 8 years ago · Apr 21, 2018, 01:24 PM
1module MetaMaster
2 #include class methods
3 def self.included(c)
4 name = c.name.underscore
5 foreign_key = "#{name}_id"
6 create_meta_fields_table("#{name}_metas",foreign_key)
7 sub_class_name = c.name + 'Meta'
8 c.instance_eval <<-"end;"
9 class ::#{sub_class_name} < Meta
10 end
11
12 def self.meta
13 ::#{sub_class_name}
14 end
15 end;
16
17 c.class_eval <<-"end;"
18 has_one :meta, class_name: '::#{sub_class_name}'
19 end;
20
21 c.extend(ClassMethods)
22 end
23 #Class scope methods
24 module ClassMethods
25
26 end
27 private
28 def self.create_meta_fields_table(name,foreign_key)
29 sql = "CREATE TABLE if not exists #{name} (id int(11) DEFAULT NULL auto_increment PRIMARY KEY,
30 #{foreign_key} int(11) not null,
31 created_at timestamp,
32 updated_at timestamp
33 ) ENGINE = MYISAM"
34 ActiveRecord::Base.connection.execute(sql)
35 end
36 public
37 class Meta < ActiveRecord::Base
38 attr_accessor :foreign_key
39
40 self.abstract_class = true
41
42 def self.add_column(*col_def)
43 self.connection.change_table(self.table_name) do |t|
44 t.column *col_def
45 end
46 end
47
48 # arraries of column defs array just like in migrations
49 def self.add_columns(col_defs=[])
50 self.connection.change_table(self.table_name) do |t|
51 col_defs.each do |col_def|
52 t.column *col_def
53 end
54 end
55 end
56
57 def self.protected_columns
58 cols =self.column_names[0..1]
59 cols + ['created_at','updated_at']
60 end
61
62 # Call just like rails method on connection
63 # EX:
64 # rename_column(:foo,:bar) or rename_column('foo','bar')
65 def self.rename_column(old_name, new_name)
66 raise "No no no" if self.protected_columns.include?(old_name.to_s)
67 self.connection.rename_column(self.table_name,old_name, new_name)
68 self.reset_column_information
69 end
70
71 def self.change_column(*col_def)
72 raise "No no no" if self.protected_columns.include?(col_def.first.to_s)
73 self.connection.change_table(self.table_name) do |t|
74 t.change *col_def
75 end
76 self.reset_column_information
77 end
78
79 # arraries of column defs array just like in migrations
80 # Ex:
81 # change_columns([[:foo, :string, limit: 100],[:bar, :number, default: 100]]
82 def self.change_columns(col_defs=[])
83 col_defs.each do |col_def|
84 self.change_column(*col_def)
85 end
86 end
87
88 def self.remove_columns(*cols)
89 check_columns = self.column_names- protected_columns
90 logger.debug(cols.inspect)
91 cols = cols & check_columns
92 logger.debug(cols)
93 self.connection.remove_columns(self.table_name,*cols)
94 self.reset_column_information
95 end
96
97 # Return the information in a simple name/type array of hashes
98 def self.info
99 columns.map do |column|
100 {name: column.name, type: column.type} unless protected_columns.include?(column.name)
101 end.compact!
102 end
103 end
104end