Skip to content

Instantly share code, notes, and snippets.

@jasim
Created January 24, 2021 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasim/db45a6be0704b480fb83349f559dd659 to your computer and use it in GitHub Desktop.
Save jasim/db45a6be0704b480fb83349f559dd659 to your computer and use it in GitHub Desktop.
# To execute:
# ruby ar_sample_impl.rb
require 'pp'
class ActiveRecord
class Migration
# See original implementation of `create_table` in ActiveRecord:
# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb#L296
def self.create_table(table_name)
migration = CreateTableDefinition.new(table_name)
# `yield` will execute the block that is passed to the `create_table` method. The block
# can take a parameter, in our case it is `|t|`. The parameter for yield, here `migration`, will
# take the place of `t`.
yield(migration)
migration.execute
end
end
end
class ActiveRecord
class CreateTableDefinition
attr_reader :table_name, :entries
def initialize(table_name)
@table_name = table_name
@entries = []
end
# See original implementation of the `column` method in ActiveRecord:
# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb#L398
def column(column_name, column_type)
@entries.push({ type: :column, column_name: column_name, column_type: column_type })
end
def execute
# Here is where we actually execute the migration. ActiveRecord will create the appropriate SQL instructions
# and run them on the server, but we'll only print out the collected migration information.
puts "create_table migration: #{table_name}"
entries.each do |entry|
pp entry
end
end
end
end
ActiveRecord::Migration.create_table(:todos) do |t|
t.column :todo_text, :text
t.column :due_date, :date
t.column :completed, :bool
end
# Running this will print the following to console:
#
# create_table migration: todos
# {:type=>:column, :column_name=>:todo_text, :column_type=>:text}
# {:type=>:column, :column_name=>:due_date, :column_type=>:date}
# {:type=>:column, :column_name=>:completed, :column_type=>:bool}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment