rails-code-generator 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae730a9fa958ca9c87a6208933bf17a6ae68abcb59ffa7ca8a5a38e11433d619
4
- data.tar.gz: 7961f74bcae4ef3f11a5881f0e9443ece5efac17e08839f7c5cc4530ca2765d3
3
+ metadata.gz: 1787e88d10c2e47cbe9fdafa9ec47b61cb8dde03907191fcc5344f186f69cf9c
4
+ data.tar.gz: 8bdfd7f36fd83cffdf6c57d7ecf35f345f7bac31434528a50b4935338b8ae2cb
5
5
  SHA512:
6
- metadata.gz: 9e11301d2a0d69a8f36d8be68f2474a6579b5e3a71349169cd04f44b3f56dda8eb5258e680963355c73bee12f8b4b190ec32f9143535cf0de8935d7912336040
7
- data.tar.gz: 72dab9e9cef3b342762ca8478a46e0c0ec778f2d4804e8c79995b4863bed5e6c5e13bbed8e39d4f44fa473c6a017caabe0b4e37d04459bd83db705e7bf0c0a20
6
+ metadata.gz: a0181136e1aa0097fe93fdcc0c54931dd0b058f2a8e264184e6b877c9714d2cec6650231756daebfffe2a2a912b62aaeabc508782f550972e57856d906b15c02
7
+ data.tar.gz: f1036a08400cfe4b7d522dd9fd4bf600d5f783b120c04306e0b75b7ddeea8482652ee72f49afaaf60033491f508ae5a0e9bb7bb1570fd76bdc0bbdb1b9546afa
@@ -3,10 +3,12 @@
3
3
  require "rails/generators"
4
4
  require "rails/generators/named_base"
5
5
  require "rails/code/generator/naming"
6
+ require "rails/code/generator/model_attributes"
6
7
 
7
8
  module RailsCodeGenerator
8
9
  class ResourcesGenerator < Rails::Generators::NamedBase
9
10
  include Rails::Code::Generator::Naming
11
+ include Rails::Code::Generator::ModelAttributes
10
12
 
11
13
  class_option :bulk, type: :boolean, default: false, desc: "Generate bulk endpoints"
12
14
 
@@ -29,6 +31,10 @@ module RailsCodeGenerator
29
31
  File.join("app/validators", table_name, "update_validator.rb")
30
32
  end
31
33
 
34
+ def create_normalizer
35
+ template "shared/normalizer.rb", File.join("app/normalizers", "#{table_name}_normalizer.rb")
36
+ end
37
+
32
38
  def create_request_specs
33
39
  template "shared/index_spec.rb", File.join("spec/requests", table_name, "index_spec.rb")
34
40
  template "shared/show_spec.rb", File.join("spec/requests", table_name, "show_spec.rb")
@@ -3,6 +3,7 @@
3
3
  module <%= resource_module_name %>
4
4
  class Build
5
5
  PERMITTED_ATTRIBUTES = [
6
+ <%= permitted_attributes_list %>
6
7
  ].freeze
7
8
 
8
9
  def self.call params
@@ -4,7 +4,7 @@ module <%= resource_module_name %>
4
4
  class CreateValidator < BaseValidator
5
5
  params do
6
6
  required(:<%= table_name %>).maybe :hash do
7
- # TODO: add attributes
7
+ <%= validator_attributes_list %>
8
8
  end
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@
3
3
  module <%= resource_module_name %>
4
4
  class Update
5
5
  PERMITTED_ATTRIBUTES = [
6
- :id,
6
+ <%= permitted_attributes_list(include_id: true) %>
7
7
  ].freeze
8
8
 
9
9
  def self.call params
@@ -4,7 +4,7 @@ module <%= resource_module_name %>
4
4
  class UpdateValidator < BaseValidator
5
5
  params do
6
6
  required(:<%= table_name %>).maybe :hash do
7
- # TODO: add attributes
7
+ <%= validator_attributes_list %>
8
8
  end
9
9
  end
10
10
  end
@@ -5,7 +5,7 @@ require "rails_helper"
5
5
  RSpec.describe "[GET] /<%= route_path %>", type: :request do
6
6
  Given(:path) { "/<%= route_path %>" }
7
7
  Given(:user) { create :user }
8
- Given(:<%= singular_name %>) { create :<%= singular_name %> }
8
+ Given!(:<%= singular_name %>) { create :<%= singular_name %> }
9
9
 
10
10
  context "with authenticated user and valid params" do
11
11
  When { get path, headers: api_auth_headers(user) }
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= resource_normalizer_class %> < BaseResponseNormalizer
4
+ attributes(
5
+ <%= normalizer_attributes_list %>
6
+ )
7
+ end
@@ -3,6 +3,7 @@
3
3
  module <%= resource_module_name %>
4
4
  class Build
5
5
  PERMITTED_ATTRIBUTES = [
6
+ <%= permitted_attributes_list %>
6
7
  ].freeze
7
8
 
8
9
  def self.call params
@@ -20,7 +20,7 @@ class <%= resource_controller_class %> < ApplicationController
20
20
  def create
21
21
  validator = <%= resource_module_name %>::CreateValidator.call params
22
22
  errors = ValidationErrorFormatter.call validator
23
- validated_params = validator.to_h
23
+ validated_params = validator.to_h[:<%= singular_name %>]
24
24
 
25
25
  if errors.empty?
26
26
  <%= singular_name %> = <%= resource_module_name %>::Build.call validated_params
@@ -33,7 +33,7 @@ class <%= resource_controller_class %> < ApplicationController
33
33
  def update
34
34
  validator = <%= resource_module_name %>::UpdateValidator.call params
35
35
  errors = ValidationErrorFormatter.call validator
36
- validated_params = validator.to_h
36
+ validated_params = validator.to_h[:<%= singular_name %>]
37
37
 
38
38
  if errors.empty?
39
39
  <%= singular_name %> = <%= class_name %>.find params[:id]
@@ -4,7 +4,7 @@ module <%= resource_module_name %>
4
4
  class CreateValidator < BaseValidator
5
5
  params do
6
6
  required(:<%= singular_name %>).maybe :hash do
7
- # TODO: add attributes
7
+ <%= validator_attributes_list %>
8
8
  end
9
9
  end
10
10
  end
@@ -10,7 +10,6 @@ RSpec.describe "[DELETE] /<%= route_path %>/:id", type: :request do
10
10
  context "with authenticated user" do
11
11
  When { delete path, headers: api_auth_headers(user) }
12
12
 
13
- Then { expect(response_body[:errors]).to be_empty }
14
- And { expect(response).to be_successful }
13
+ Then { expect(response).to be_successful }
15
14
  end
16
15
  end
@@ -3,6 +3,7 @@
3
3
  module <%= resource_module_name %>
4
4
  class Update
5
5
  PERMITTED_ATTRIBUTES = [
6
+ <%= permitted_attributes_list %>
6
7
  ].freeze
7
8
 
8
9
  def self.call <%= singular_name %>, params
@@ -4,7 +4,7 @@ module <%= resource_module_name %>
4
4
  class UpdateValidator < BaseValidator
5
5
  params do
6
6
  required(:<%= singular_name %>).maybe :hash do
7
- # TODO: add attributes
7
+ <%= validator_attributes_list %>
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Code
5
+ module Generator
6
+ module ModelAttributes
7
+ EXCLUDED_COLUMNS = %w[id created_at updated_at].freeze
8
+
9
+ DRY_TYPE_MAP = {
10
+ "string" => :string,
11
+ "text" => :string,
12
+ "citext" => :string,
13
+ "integer" => :integer,
14
+ "bigint" => :integer,
15
+ "float" => :float,
16
+ "decimal" => :decimal,
17
+ "boolean" => :bool,
18
+ "date" => :date,
19
+ "datetime" => :time,
20
+ "timestamp" => :time,
21
+ "timestamptz" => :time,
22
+ "json" => :hash,
23
+ "jsonb" => :hash,
24
+ "uuid" => :string,
25
+ }.freeze
26
+
27
+ def model_attributes
28
+ @model_attributes ||= fetch_model_attributes
29
+ end
30
+
31
+ def permitted_attributes_list(include_id: false)
32
+ names = model_attribute_names
33
+ names = [:id, *names] if include_id
34
+ format_symbol_list(names)
35
+ end
36
+
37
+ def normalizer_attributes_list
38
+ names = model_attribute_names
39
+ return " # TODO: add attributes" if names.empty?
40
+
41
+ format_symbol_list(names, indent: 4)
42
+ end
43
+
44
+ def validator_attributes_list
45
+ return " # TODO: add attributes" if model_attributes.empty?
46
+
47
+ model_attributes.map { |attribute| validator_line_for(attribute) }.join("\n")
48
+ end
49
+
50
+ private
51
+
52
+ def model_attribute_names
53
+ model_attributes.map { |attribute| attribute[:name].to_sym }
54
+ end
55
+
56
+ def format_symbol_list(names, indent: 6)
57
+ padding = " " * indent
58
+ names.map { |name| "#{padding}:#{name}," }.join("\n")
59
+ end
60
+
61
+ def validator_line_for(attribute)
62
+ name = attribute[:name]
63
+ dry_type = attribute[:dry_type]
64
+
65
+ if dry_type
66
+ " optional(:#{name}).maybe :#{dry_type}"
67
+ else
68
+ " optional(:#{name})"
69
+ end
70
+ end
71
+
72
+ def fetch_model_attributes
73
+ klass = class_name.constantize
74
+ return [] unless klass.respond_to?(:columns)
75
+
76
+ klass.columns.filter_map do |column|
77
+ next if EXCLUDED_COLUMNS.include?(column.name)
78
+
79
+ {
80
+ name: column.name,
81
+ dry_type: DRY_TYPE_MAP[column.type.to_s],
82
+ }
83
+ end
84
+ rescue StandardError
85
+ []
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -3,7 +3,7 @@
3
3
  module Rails
4
4
  module Code
5
5
  module Generator
6
- VERSION = "0.1.0"
6
+ VERSION = "0.1.1"
7
7
  end
8
8
  end
9
9
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "generator/version"
4
4
  require_relative "generator/naming"
5
+ require_relative "generator/model_attributes"
5
6
 
6
7
  module Rails
7
8
  module Code
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-code-generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Sweat
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-31 00:00:00.000000000 Z
11
+ date: 2026-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -49,6 +49,7 @@ files:
49
49
  - lib/generators/rails_code_generator/resources/templates/bulk/update_spec.rb.tt
50
50
  - lib/generators/rails_code_generator/resources/templates/bulk/update_validator.rb.tt
51
51
  - lib/generators/rails_code_generator/resources/templates/shared/index_spec.rb.tt
52
+ - lib/generators/rails_code_generator/resources/templates/shared/normalizer.rb.tt
52
53
  - lib/generators/rails_code_generator/resources/templates/shared/show_spec.rb.tt
53
54
  - lib/generators/rails_code_generator/resources/templates/single/build.rb.tt
54
55
  - lib/generators/rails_code_generator/resources/templates/single/controller.rb.tt
@@ -60,6 +61,7 @@ files:
60
61
  - lib/generators/rails_code_generator/resources/templates/single/update_spec.rb.tt
61
62
  - lib/generators/rails_code_generator/resources/templates/single/update_validator.rb.tt
62
63
  - lib/rails/code/generator.rb
64
+ - lib/rails/code/generator/model_attributes.rb
63
65
  - lib/rails/code/generator/naming.rb
64
66
  - lib/rails/code/generator/railtie.rb
65
67
  - lib/rails/code/generator/version.rb