Class: ModelBase::MetaModel

Inherits:
Object
  • Object
show all
Defined in:
lib/model_base/meta_model.rb

Constant Summary collapse

SPEC_EXCLUSED_COLS =
%w[id created_at updated_at]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ MetaModel

Returns a new instance of MetaModel.



7
8
9
# File 'lib/model_base/meta_model.rb', line 7

def initialize(name)
  @name = name
end

Instance Attribute Details

#nameObject (readonly) Also known as: class_name

Returns the value of attribute name.



6
7
8
# File 'lib/model_base/meta_model.rb', line 6

def name
  @name
end

Instance Method Details

#[](name) ⇒ Object



69
70
71
# File 'lib/model_base/meta_model.rb', line 69

def [](name)
  raw_columns.detect{|c| c.name == name.to_s}
end

#active_record?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/model_base/meta_model.rb', line 37

def active_record?
  defined?(ActiveRecord) == "constant" && ActiveRecord.class == Module && model_class < ActiveRecord::Base
end

#all_dependencies(required = true) ⇒ Object



110
111
112
# File 'lib/model_base/meta_model.rb', line 110

def all_dependencies(required = true)
  dependencies.values.map{|m| [m] + m.all_dependencies(required)}.flatten.uniq(&:name)
end

#columnsObject



73
74
75
76
# File 'lib/model_base/meta_model.rb', line 73

def columns
  @columns ||=
    title_column ? raw_columns : [ColumnAttribute.new(self, 'id', :integer, title: true)] + raw_columns
end

#columns_for(type) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/model_base/meta_model.rb', line 79

def columns_for(type)
  case type
  when :form, :index, :show
    columns.reject{|c| exclude_for?(type, c) }
  when :params     then columns_for(:form).reject{|c| c.name.to_s == 'id'}
  when :spec_index then columns_for(:index).reject{|c| SPEC_EXCLUSED_COLS.include?(c.name)}
  when :spec_show  then columns_for(:show ).reject{|c| SPEC_EXCLUSED_COLS.include?(c.name)}
  when :factory     then columns_for(:params).reject{|c| SPEC_EXCLUSED_COLS.include?(c.name)}
  else
    raise "Unknown template type: #{type.inspect}"
  end
end

#dependencies(required = true) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/model_base/meta_model.rb', line 97

def dependencies(required = true)
  # c: c.required?
  # r: required (the argument)
  #
  # | c \ r | true  | false |
  # |-------|-------|-------|
  # | true  | true  | true  |
  # | false | false | true  |
  raw_columns.select{|c| !required || c.required? }.
    select(&:reference).
    each_with_object({}){|c,d| d[c.reference.name] = c.ref_model }
end

#exclude_for?(type, col_attr) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
# File 'lib/model_base/meta_model.rb', line 92

def exclude_for?(type, col_attr)
  excluded_columns = ModelBase.config.send("excluded_columns_of_#{type}")
  excluded_columns.any?{|ex| ex === col_attr.name && !col_attr.title? }
end

#factory_girl_let_definition(action: :create) ⇒ Object



135
136
137
# File 'lib/model_base/meta_model.rb', line 135

def factory_girl_let_definition(action: :create)
  'let(:%s) { %s }' % [full_resource_name, factory_girl_to(action)]
end

#factory_girl_let_definitions(spacer = " ") ⇒ Object



139
140
141
142
143
144
# File 'lib/model_base/meta_model.rb', line 139

def factory_girl_let_definitions(spacer = "  ")
  deps = all_dependencies
  r = deps.reverse.map(&:factory_girl_let_definition)
  r << "let(:user){ FactoryGirl.create(:user) }" unless deps.any?{|m| m.full_resource_name == 'user' }
  r.join("\n" << spacer)
end

#factory_girl_method(name, extra) ⇒ Object



118
119
120
121
122
123
# File 'lib/model_base/meta_model.rb', line 118

def factory_girl_method(name, extra)
  extra_str = extra.blank? ? '' : ', ' << extra.map{|k,v| "#{k}: '#{v}'"}.join(', ')
  options = factory_girl_options
  options_str = options.empty? ? '' : ', ' <<  factory_girl_options.join(', ')
  'FactoryGirl.%s(:%s%s%s)' % [name, full_resource_name, options_str, extra_str]
end

#factory_girl_optionsObject



114
115
116
# File 'lib/model_base/meta_model.rb', line 114

def factory_girl_options
  dependencies.map{|attr, model| "#{attr}: #{model.full_resource_name}" }
end

#factory_girl_to(name, context: nil, index: 1, extra: {}) ⇒ Object



125
126
127
128
129
130
131
132
133
# File 'lib/model_base/meta_model.rb', line 125

def factory_girl_to(name, context: nil, index: 1, extra: {})
  case context
  when :spec_index
    columns_for(:spec_index).delete_if(&:single_sample_only?).delete_if(&:reference).each do |col|
      extra[col.name] = col.sample_value(index)
    end
  end
  factory_girl_method(name, extra)
end

#full_resource_nameObject



25
26
27
# File 'lib/model_base/meta_model.rb', line 25

def full_resource_name
  name.underscore.gsub('/', '_').sub(/\A_/, '')
end

#model_classObject



33
34
35
# File 'lib/model_base/meta_model.rb', line 33

def model_class
  @model_class ||= name.constantize
end

#plural_full_resource_nameObject



29
30
31
# File 'lib/model_base/meta_model.rb', line 29

def plural_full_resource_name
  full_resource_name.pluralize
end

#plural_nameObject



13
14
15
# File 'lib/model_base/meta_model.rb', line 13

def plural_name
  name.pluralize
end

#plural_resource_nameObject



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

def plural_resource_name
  resource_name.pluralize
end

#raw_columnsObject



65
66
67
# File 'lib/model_base/meta_model.rb', line 65

def raw_columns
  @raw_columns ||= retrieve_columns
end

#resource_nameObject



17
18
19
# File 'lib/model_base/meta_model.rb', line 17

def resource_name
  name.demodulize.underscore
end

#retrieve_columnsObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/model_base/meta_model.rb', line 46

def retrieve_columns
  raw_cols = active_record? ? model_class.columns : model_class.fields.map {|c| c[1] }
  belongs_to_refs = model_class.reflections.values.select{|ref| ref.is_a?(ActiveRecord::Reflection::BelongsToReflection) }
  cols = raw_cols.map do |col|
    ref = belongs_to_refs.detect{|ref| ref.foreign_key == col.name}
    ColumnAttribute.new(self, col.name, col.type, column: col, reference: ref)
  end
  @title_column = nil
  ModelBase.config.title_column_candidates.each do |tcc|
    @title_column = cols.detect{|col| tcc === col.name}
    if @title_column
      @title_column.title = true
      break
    end
  end
  @title_column.linkable = true if @title_column
  cols
end

#sample_valueObject



146
147
148
# File 'lib/model_base/meta_model.rb', line 146

def sample_value
  @sample_value ||= name.split('').map(&:ord).sum
end

#title_columnObject



41
42
43
44
# File 'lib/model_base/meta_model.rb', line 41

def title_column
  retrieve_columns unless defined?(@title_column)
  @title_column
end