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.



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

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.



12
13
14
# File 'lib/migrant/schema.rb', line 12

def columns
  @columns
end

#indexesObject

Returns the value of attribute indexes.



12
13
14
# File 'lib/migrant/schema.rb', line 12

def indexes
  @indexes
end

#validationsObject

Returns the value of attribute validations.



12
13
14
# File 'lib/migrant/schema.rb', line 12

def validations
  @validations
end

Instance Method Details

#add_association(association) ⇒ Object



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

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



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

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



54
55
56
# File 'lib/migrant/schema.rb', line 54

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

#define_structure(type, &block) ⇒ Object



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

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)


50
51
52
# File 'lib/migrant/schema.rb', line 50

def partial?
  @type == :partial
end

#requires_migration?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/migrant/schema.rb', line 45

def requires_migration?
  true
end