Skip to content

Instantly share code, notes, and snippets.

@ajsharp
Last active March 24, 2019 21:36
Show Gist options
  • Save ajsharp/2626cc5e881791714b76c8a634745ab8 to your computer and use it in GitHub Desktop.
Save ajsharp/2626cc5e881791714b76c8a634745ab8 to your computer and use it in GitHub Desktop.
TYPEMAP = {
String => 'String',
Integer => 'Int',
DateTime => 'ISO8601DateTime',
Boolean => 'Boolean',
BSON::ObjectId => 'String'
}
def get_type(field_type)
TYPEMAP[field_type] || "Types::#{field_type}Type"
end
namespace :graphql do
task :generate_model, [:model] => :environment do |t, args|
model = args[:model].constantize
filename = "#{args[:model].underscore}_type.rb"
relations = model.relations
assocs = relations.map do |key, field|
"field :#{key}, Types::#{field.class_name}Type, null: true"
end
fields = model.fields.map do |key, field|
"field :#{key}, #{get_type(field.type)}, null: true"
end
klass = <<-STR
module Types
class #{model}Type < Types::BaseObject
#{fields.join("\n ")}
#{assocs.join("\n ")}
end
end
STR
path = Rails.root.join('app', 'graphql', 'types', filename)
if File.exists?(path)
puts "A type already exists for #{model}"
else
File.write(path, klass)
end
end
end
const fs = require('fs')
const path = require('path')
const snake = require('snake-case')
const Inflector = require('inflected')
const globby = require('globby')
const fieldMapping = {
'String': 'String',
'Date': 'DateTime',
'Boolean': 'Boolean',
'Number': 'Integer',
'Array': 'Array',
'Mixed': 'Hash'
}
function convertModel(model) {
let models = []
const collectionName = model.collection.name
const modelName = model.modelName
const filename = `${snake(modelName).toLowerCase()}.rb`
const fields = []
const associations = []
const restrictedFields = ['__v', '_id']
const entries = Object.entries(model.schema.paths).filter(([field, _]) => !restrictedFields.includes(field))
for (let [field, schema] of entries) {
const fieldType = schema.instance
if (field === '__v') continue
if (schema.options.ref) { // association
associations.push(`belongs_to :${field}, class_name: '${schema.options.ref}'`)
} else { // field
const mappedtype = fieldMapping[fieldType]
if (!mappedtype) throw new Error(`no mapping for type=${fieldType}`)
fields.push(`field :${field}, type: ${mappedtype}`)
}
}
const code = `
class ${modelName}
include Mongoid::Document
include Mongoid::Timestamps
store_in :collection: '${collectionName}'
${fields.join("\n ")}
${associations.join("\n ")}
end
`
return {code, filename}
}
const MODEL_PATHS = globby.sync('./dist/server/models/*.js')
const OUT_PATH = path.resolve('/NEW_PROJECT_PATH/app/models')
const models = MODEL_PATHS.map(path => {
var modelName = path.split('/').reverse()[0].replace('.js', '')
var model = require(`.${path}`)[modelName]
console.log('converting', modelName)
if (!model) {
console.error("No model export for", modelName)
} else {
return convertModel(model)
}
}).filter(Boolean)
models.forEach(({code, filename}) => {
fs.writeFileSync(path.join(OUT_PATH, filename), code)
})
console.log(models.join("\n"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment