Created
July 13, 2020 18:06
-
-
Save iftheshoefritz/7a195eb5676bb790cdbff91ab7d42f31 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
namespace :solargraph do | |
task generate: :environment do | |
# Add the folder you choose in your config/application.rb | |
# example: | |
# config.autoload_paths << Rails.root.join('app/solargraph') | |
gen_directory = Rails.root.join("config", "yard") | |
# run the script as a rails runner: | |
# jundle exec rails r ./bin/generate_solar_models.rb | |
# if you wanted to choose specific models to generate for | |
# models = [User] | |
Rails.application.eager_load! | |
models = ApplicationRecord.descendants | |
puts("generating for #{models.count} models") | |
models.each do |model| | |
puts "processing #{model.name}." | |
columns = model.columns.map do |col| | |
type = type_translation[col.type] | |
<<~TXT | |
# @!attribute #{col.name} | |
# @return [#{type}] | |
TXT | |
end | |
reflections = model.reflections.map do |key, reflection| | |
type = reflection_comment(reflection) | |
puts "KEY: #{key} TYPE: #{type}" | |
next if type.nil? | |
<<~TXT | |
# @!attribute #{key} | |
# @return #{type} | |
TXT | |
end | |
generated_attributes = <<~TXT | |
class #{model.name} | |
#{reflections.join("\n")} | |
#{columns.join("\n")} | |
end | |
TXT | |
path = gen_directory.join("#{model.model_name.singular}.rb") | |
File.write(path, generated_attributes) | |
puts("written : #{path}") | |
end | |
end | |
def type_translation | |
{ | |
decimal: "Decimal", | |
integer: "Int", | |
date: "Date", | |
datetime: "DateTime", | |
string: "String", | |
boolean: "Bool" | |
} | |
end | |
def class_for(name) | |
name = name.to_s | |
found = ApplicationRecord.descendants.detect do |model| | |
model.model_name.plural == name || model.model_name.singular == name | |
end | |
found&.first&.model_name&.name | |
end | |
def reflection_type(reflection) | |
puts "Reflecting with #{reflection}" | |
case reflection | |
when ActiveRecord::Reflection::HasManyReflection | |
:many | |
when ActiveRecord::Reflection::HasAndBelongsToManyReflection | |
:many | |
when ActiveRecord::Reflection::HasOneReflection | |
:one | |
when ActiveRecord::Reflection::BelongsToReflection | |
:one | |
when ActiveRecord::Reflection::ThroughReflection | |
reflection_type(reflection.through_reflection) | |
else | |
puts("# cannot infer association for #{reflection.name} -> #{reflection.class}") | |
nil | |
end | |
end | |
def reflection_class_name(reflection) | |
case reflection | |
when ActiveRecord::Reflection::HasManyReflection | |
class_name = | |
if reflection.options[:class_name].present? | |
reflection.options[:class_name] | |
else | |
class_for(reflection.name) | |
end | |
class_name | |
when ActiveRecord::Reflection::ThroughReflection | |
class_name = | |
if reflection.options[:class_name].present? | |
reflection.options[:class_name] | |
else | |
class_for(reflection.name) | |
end | |
class_name | |
when ActiveRecord::Reflection::HasAndBelongsToManyReflection | |
class_name = | |
if reflection.options[:class_name].present? | |
reflection.options[:class_name] | |
else | |
class_for(reflection.name) | |
end | |
class_name | |
when ActiveRecord::Reflection::HasOneReflection | |
reflection.name.to_s.capitalize | |
when ActiveRecord::Reflection::BelongsToReflection | |
reflection.name.to_s.capitalize | |
else | |
puts("# cannot infer association for #{reflection.name} -> #{reflection.class}") | |
nil | |
end | |
end | |
def reflection_comment(reflection) | |
case reflection_type(reflection) | |
when :one | |
"[#{reflection_class_name(reflection)}]" | |
when :many | |
"[Array<#{reflection_class_name(reflection)}>]" | |
end | |
end | |
end |
@iftheshoefritz What's the instruction here? How do I ran this file and where do I put it?
@guledali, sorry I didn't spot your question here for so long. Check out the Rails thread in the solargraph project: castwide/solargraph#87 and also the gem solargraph-rails.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Like the name of the file says, this is plagiarized / heavily influenced by this example: https://gist.github.com/hellola/b832cff599f67a5e353e6af4914d467a