Class: Migrant::Schema

Inherits:
Object
  • Object
show all
Defined in:
lib/migrant/schema.rb

Overview

Converts the following DSL:

class MyModel < ActiveRecord::Base

structure do
  my_field "some string"
 end

end into a schema on that model class by calling method_missing(my_field) and deciding what the best schema type is for the user’s requiredments

Direct Known Subclasses

InheritedSchema

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSchema

Returns a new instance of Schema.



16
17
18
19
20
21
22
# File 'lib/migrant/schema.rb', line 16

def initialize
  @proxy = SchemaProxy.new(self)
  @columns = Hash.new
  @indexes = Array.new
  @validations = Hash.new
  @type = :default
end

Instance Attribute Details

#columnsObject

Returns the value of attribute columns.



14
15
16
# File 'lib/migrant/schema.rb', line 14

def columns
  @columns
end

#indexesObject

Returns the value of attribute indexes.



14
15
16
# File 'lib/migrant/schema.rb', line 14

def indexes
  @indexes
end

#validationsObject

Returns the value of attribute validations.



14
15
16
# File 'lib/migrant/schema.rb', line 14

def validations
  @validations
end

Instance Method Details

#add_association(association) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/migrant/schema.rb', line 32

def add_association(association)
  # Rails 3.1 changes primary_key_name to foreign_key (correct behaviour), so this is essentially backwards compatibility for Rails 3.0
  field = (association.respond_to?(:foreign_key))? association.foreign_key.to_sym : association.primary_key_name.to_sym
  
  case association.macro
    when :belongs_to
      if association.options[:polymorphic]
        @columns[(association.name.to_s+'_type').to_sym] = DataType::Polymorphic.new(:field => field)
        @indexes << [(association.name.to_s+'_type').to_sym, field]
      end
      @columns[field] = DataType::ForeignKey.new(:field => field)
      @indexes << field
  end
end

#add_field(field, data_type = nil, options = {}) ⇒ Object

This is where we decide what the best schema is based on the structure requirements The output of this is essentially a formatted schema hash that is processed on each model by Migrant::MigrationGenerator



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
# File 'lib/migrant/schema.rb', line 64

def add_field(field, data_type = nil, options = {})
  data_type = DataType::String if data_type.nil?
  puts [":#{field}", "#{data_type.class.to_s}", "#{options.inspect}"].collect { |s| s.ljust(25) }.join if ENV['DEBUG']
  
  # Fields that do special things go here.
  if field == :timestamps
    add_field(:updated_at, :datetime)
    add_field(:created_at, :datetime)
    return true
  end

  # Add index if explicitly asked
  @indexes << field if options.delete(:index) || data_type.class.to_s == 'Hash' && data_type.delete(:index)
  @validations[field] = options.delete(:validates) if options[:validates]
  options.merge!(:field => field)    
  
  # Matches: description DataType::Paragraph, :index => true
  if data_type.is_a?(Class) && data_type.respond_to?(:migrant_data_type?)
    @columns[field] = data_type.new(options)
  # Matches: description :index => true, :unique => true
  else
    begin
      # Eg. "My field" -> String -> DataType::String
      @columns[field] = "DataType::#{data_type.class.to_s}".constantize.new(options.merge(:value => data_type))
    rescue NameError
      # We don't have a matching type, throw a warning and default to string
      puts "MIGRATION WARNING: No migration implementation for class #{data_type.class.to_s} on field '#{field}', defaulting to string..."
      @columns[field] = DataType::Base.new(options)
    end
  end
end

#column_migrationsObject



56
57
58
# File 'lib/migrant/schema.rb', line 56

def column_migrations
  @columns.collect {|field, data| [field, data.column] } # All that needs to be migrated
end

#define_structure(type, &block) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/migrant/schema.rb', line 24

def define_structure(type, &block)
  @validations = Hash.new
  @type = type if type

  # Runs method_missing on columns given in the model "structure" DSL
  @proxy.translate_fancy_dsl(&block) if block_given?
end

#partial?Boolean

If the user defines structure(:partial), irreversible changes are ignored (removing a column, for example)

Returns:

  • (Boolean)


52
53
54
# File 'lib/migrant/schema.rb', line 52

def partial?
  @type == :partial
end

#requires_migration?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/migrant/schema.rb', line 47

def requires_migration?
  true
end