Skip to content

Instantly share code, notes, and snippets.

@oogali
Last active October 1, 2015 17:58
Show Gist options
  • Save oogali/2034390 to your computer and use it in GitHub Desktop.
Save oogali/2034390 to your computer and use it in GitHub Desktop.
Dirty hax to make models from Hash 'documents'
!/usr/bin/env ruby
require 'rubygems'
require 'time'
require 'active_support/core_ext/string'
class ForeignKey
end
FOREIGN_KEY = ForeignKey.new
$models = []
def class_to_column(klass)
case klass
when String:
'string'
when Date:
'timestamp'
when Time:
'timestamp'
when TrueClass:
'boolean'
when FalseClass:
'boolean'
when Fixnum:
'integer'
when Float:
'numeric'
when ForeignKey:
'references'
else
'column'
end
end
def create_model(classname, obj, ref = [])
more_models = []
model = <<-EOF
class #{classname}Table < ActiveRecord::Migration
def self.up
create_table :#{classname.downcase} do |t|
t.primary_key :id
EOF
model += ' '
if ref
ref.each do |r|
model += "t.references :#{r.downcase.singularize}"
model += "\n "
end
end
obj = obj.first if obj.is_a?(Array) and obj.first.is_a?(Hash)
if obj.is_a?(Hash)
model += obj.keys.map { |k|
if obj[k].is_a?(Array) or obj[k].is_a?(Hash)
more_models << k
next
end
"t.#{class_to_column(obj[k])} :#{k}"
}.reject { |c| c.nil? }.join("\n ")
elsif obj.is_a?(Array)
model += "t.#{class_to_column(obj.first)} :#{classname.downcase}"
end
model += <<-EOF
t.timestamps
end
EOF
ref.each do |r|
model += " add_index :#{classname.downcase}, [ :#{r.downcase.singularize}_id ]\n"
end
model += <<-EOF
end
def self.down
drop_table :#{classname.downcase}
end
end
EOF
unless more_models.empty?
more_models.each do |m|
create_model m.to_s.capitalize, obj[m], (ref + [classname])
end
end
$models << { :name => classname, :model => model }
true
end
def write_models(dir = nil)
version = 0
Dir[File.join(dir, '*.rb')].entries.each do |fn|
m = fn.match(/(\d+)_/)
next unless m
version = [version, m[1].to_i].max
end if dir
$models.reverse.each do |m|
puts "# ***** #{m[:name]} *****"
puts m[:model]
puts
if dir
version += 1
fn = File.join dir, "#{'%03d' % version}_create_#{m[:name].downcase}_table.rb"
f = File.open fn, 'a+'
f.write m[:model]
f.close
end
end
end
unless ARGV.length >= 2
puts "#{$0} <class name> <filename.rb> <output directory>"
exit 1
end
classname = ARGV.shift.capitalize
doc = eval File.read(ARGV.shift)
outdir = ARGV.shift
create_model classname, doc
write_models outdir
require 'time'
{
'uuid' => 'unique id',
'title' => 'title',
'summary' => 'summary',
'history' => [
{ 'author' => 'oogali', 'timestamp' => Time.parse('2012-03-14 12:42:00') }
],
'tags' => [
'invoice', 'oogali', 'vendor'
],
'authorized' => [
'oogali', '@accounting'
]
}
@oogali
Copy link
Author

oogali commented Mar 14, 2012

Example output:

marvin:~ oogali$ ./makemodel.rb Documents document.rb
class DocumentsTable < ActiveRecord::Migration
  def self.up
    create_table :documents do |t|
      t.index :id
      t.string :title
      t.string :uuid
      t.string :summary
      t.timestamps
    end
  end

  def self.down
    drop_table :documents
  end
end

class HistoryTable < ActiveRecord::Migration
  def self.up
    create_table :history do |t|
      t.index :id
      t.references :documents
      t.timestamp :timestamp
      t.string :author
      t.timestamps
    end
  end

  def self.down
    drop_table :history
  end
end

class TagsTable < ActiveRecord::Migration
  def self.up
    create_table :tags do |t|
      t.index :id
      t.references :documents
      t.string :tags
      t.timestamps
    end
  end

  def self.down
    drop_table :tags
  end
end

class AuthorizedTable < ActiveRecord::Migration
  def self.up
    create_table :authorized do |t|
      t.index :id
      t.references :documents
      t.string :authorized
      t.timestamps
    end
  end

  def self.down
    drop_table :authorized
  end
end
marvin:~ oogali$ 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment