Last active
March 24, 2019 21:36
-
-
Save ajsharp/2626cc5e881791714b76c8a634745ab8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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