rails-domino 0.1.0
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 +7 -0
- data/lib/domino/base_repository.rb +26 -0
- data/lib/domino/base_service.rb +10 -0
- data/lib/domino/generators/domino/domino_generator.rb +34 -0
- data/lib/domino/generators/domino/templates/blueprint.rb.tt +10 -0
- data/lib/domino/generators/domino/templates/controller.rb.tt +50 -0
- data/lib/domino/generators/domino/templates/repository.rb.tt +42 -0
- data/lib/domino/generators/domino/templates/service.rb.tt +46 -0
- data/lib/domino/scaffolder.rb +77 -0
- data/lib/domino/version.rb +5 -0
- data/lib/domino.rb +10 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f6dba679e8094d127d345f3e8cd68115192cdf5f701b447bbe9464d0e07d0dc4
|
4
|
+
data.tar.gz: 5041c268a9e5b2e7e45711bc12482802986b0dc20f02b4b55659dd0b95ce1156
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8472903ef80712086e13011d7e8df94a1117264bc383d672bc9365ef5e96a16869cc82319276c6b75ba970958a52d0414a728e275912d55f44f82a362333a613
|
7
|
+
data.tar.gz: 2b2565ace0fdff4e6ad1bc45c9a4bae69958c11c3928980b9e6dde655467e5ad4e4a45c722882785bc6a6bec79b63e9f3d7ba6ec6b4d194982b63fb6b3d5b5ee
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Abstract base repository for all models.
|
4
|
+
#
|
5
|
+
# Subclasses must implement standard CRUD methods.
|
6
|
+
class BaseRepository
|
7
|
+
def find_by_id(_id)
|
8
|
+
raise NotImplementedError, "Subclasses must implement find_by_id"
|
9
|
+
end
|
10
|
+
|
11
|
+
def all
|
12
|
+
raise NotImplementedError, "Subclasses must implement all"
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(_attrs)
|
16
|
+
raise NotImplementedError, "Subclasses must implement create"
|
17
|
+
end
|
18
|
+
|
19
|
+
def update(_id, _attrs)
|
20
|
+
raise NotImplementedError, "Subclasses must implement update"
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(_id)
|
24
|
+
raise NotImplementedError, "Subclasses must implement delete"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
class DominoGenerator < Rails::Generators::NamedBase # rubocop:disable Style/Documentation
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
# Accept attributes for model
|
9
|
+
argument :attributes, type: :array, default: [], banner: "field[:type] field[:type]"
|
10
|
+
|
11
|
+
class_option :with_model, type: :boolean, default: false, desc: "Generate ActiveRecord model"
|
12
|
+
|
13
|
+
def create_model
|
14
|
+
return unless options[:with_model]
|
15
|
+
|
16
|
+
generate "model", "#{class_name} #{attributes.join(" ")}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_service
|
20
|
+
template "service.rb.tt", File.join("app/services", "#{file_name}_service.rb")
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_repository
|
24
|
+
template "repository.rb.tt", File.join("app/repositories", "#{file_name}_repository.rb")
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_blueprint
|
28
|
+
template "blueprint.rb.tt", File.join("app/mappers", "#{file_name}_blueprint.rb")
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_controller
|
32
|
+
template "controller.rb.tt", File.join("app/controllers", "#{file_name.pluralize}_controller.rb")
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Blueprint for serializing <%= class_name %> model.
|
2
|
+
#
|
3
|
+
# @see https://github.com/procore/blueprinter
|
4
|
+
#
|
5
|
+
class <%= class_name %>Blueprint < Blueprinter::Base
|
6
|
+
identifier :id
|
7
|
+
|
8
|
+
# Fields to expose
|
9
|
+
fields <%= attributes.map { |attr| ":#{attr.split(':').first}" }.join(', ') %>
|
10
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Controller for <%= class_name.pluralize %> API endpoints.
|
2
|
+
#
|
3
|
+
# Provides RESTful actions for <%= class_name %> resources.
|
4
|
+
#
|
5
|
+
class <%= class_name.pluralize %>Controller < ApplicationController
|
6
|
+
include Import['<%= file_name %>_service']
|
7
|
+
|
8
|
+
# GET /<%= file_name.pluralize %>
|
9
|
+
# @return [JSON]
|
10
|
+
def index
|
11
|
+
render json: <%= class_name %>Blueprint.render(@<%= file_name %>_service.all)
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /<%= file_name.pluralize %>/:id
|
15
|
+
# @param id [Integer]
|
16
|
+
# @return [JSON]
|
17
|
+
def show
|
18
|
+
render json: <%= class_name %>Blueprint.render(@<%= file_name %>_service.get(params[:id]))
|
19
|
+
end
|
20
|
+
|
21
|
+
# POST /<%= file_name.pluralize %>
|
22
|
+
# @return [JSON]
|
23
|
+
def create
|
24
|
+
obj = @<%= file_name %>_service.create(user_params)
|
25
|
+
render json: <%= class_name %>Blueprint.render(obj), status: :created
|
26
|
+
end
|
27
|
+
|
28
|
+
# PUT/PATCH /<%= file_name.pluralize %>/:id
|
29
|
+
# @param id [Integer]
|
30
|
+
# @return [JSON]
|
31
|
+
def update
|
32
|
+
obj = @<%= file_name %>_service.update(params[:id], user_params)
|
33
|
+
render json: <%= class_name %>Blueprint.render(obj)
|
34
|
+
end
|
35
|
+
|
36
|
+
# DELETE /<%= file_name %>/:id
|
37
|
+
# @param id [Integer]
|
38
|
+
# @return [JSON]
|
39
|
+
def destroy
|
40
|
+
success = @<%= file_name %>_service.delete(params[:id])
|
41
|
+
head(success ? :no_content : :not_found)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# @return [ActionController::Parameters]
|
47
|
+
def user_params
|
48
|
+
params.require(:<%= file_name %>).permit(<%= attributes.map { |a| ":#{a.split(':').first}" }.join(', ') %>)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Repository for <%= class_name %> model.
|
2
|
+
#
|
3
|
+
# Provides abstracted access to ActiveRecord persistence.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# repo = <%= class_name %>Repository.new
|
7
|
+
# repo.find_by_id(1)
|
8
|
+
#
|
9
|
+
class <%= class_name %>Repository < BaseRepository
|
10
|
+
# @param id [Integer]
|
11
|
+
# @return [<%= class_name %>, nil]
|
12
|
+
def find_by_id(id)
|
13
|
+
<%= class_name %>.find_by(id: id)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array<<%= class_name %>>]
|
17
|
+
def all
|
18
|
+
<%= class_name %>.all
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param attrs [Hash]
|
22
|
+
# @return [<%= class_name %>]
|
23
|
+
def create(attrs)
|
24
|
+
<%= class_name %>.create(attrs)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param id [Integer]
|
28
|
+
# @param attrs [Hash]
|
29
|
+
# @return [<%= class_name %>, nil]
|
30
|
+
def update(id, attrs)
|
31
|
+
record = <%= class_name %>.find_by(id: id)
|
32
|
+
record.update(attrs) if record
|
33
|
+
record
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param id [Integer]
|
37
|
+
# @return [<%= class_name %>, nil]
|
38
|
+
def delete(id)
|
39
|
+
record = <%= class_name %>.find_by(id: id)
|
40
|
+
record&.destroy
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Service for business logic around <%= class_name %>.
|
2
|
+
#
|
3
|
+
# Handles use-case orchestration and business operations.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# service = <%= class_name %>Service.new(...)
|
7
|
+
# service.get(1)
|
8
|
+
#
|
9
|
+
class <%= class_name %>Service < BaseService
|
10
|
+
include Import['<%= file_name %>_repository']
|
11
|
+
|
12
|
+
# @param <%= file_name %>_repository [<%= class_name %>Repository]
|
13
|
+
def initialize(<%= file_name %>_repository:)
|
14
|
+
@<%= file_name %>_repository = <%= file_name %>_repository
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param id [Integer]
|
18
|
+
# @return [<%= class_name %>, nil]
|
19
|
+
def get(id)
|
20
|
+
@<%= file_name %>_repository.find_by_id(id)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param attrs [Hash]
|
24
|
+
# @return [<%= class_name %>]
|
25
|
+
def create(attrs)
|
26
|
+
@<%= file_name %>_repository.create(attrs)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param id [Integer]
|
30
|
+
# @param attrs [Hash]
|
31
|
+
# @return [<%= class_name %>, nil]
|
32
|
+
def update(id, attrs)
|
33
|
+
@<%= file_name %>_repository.update(id, attrs)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param id [Integer]
|
37
|
+
# @return [Boolean]
|
38
|
+
def delete(id)
|
39
|
+
!!@<%= file_name %>_repository.delete(id)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Array<<%= class_name %>>]
|
43
|
+
def all
|
44
|
+
@<%= file_name %>_repository.all
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Domino
|
4
|
+
# Scaffolder: handles the generation of model, repository, service, blueprint, and controller files
|
5
|
+
class Scaffolder
|
6
|
+
# Entrypoint: called from Domino.scaffold
|
7
|
+
#
|
8
|
+
# @param tables [Array<String>] optional list of tables to scaffold
|
9
|
+
# @param namespace [String, nil] reserved for future support
|
10
|
+
# @param generate_model [Boolean] whether to run model generation
|
11
|
+
def self.scaffold(tables: nil, namespace: nil, generate_model: true)
|
12
|
+
connection = ActiveRecord::Base.connection
|
13
|
+
tables ||= connection.tables.reject { |t| t == "schema_migrations" }
|
14
|
+
|
15
|
+
tables.each do |table|
|
16
|
+
klass = table.singularize.camelize
|
17
|
+
columns = connection.columns(table)
|
18
|
+
ScaffoldRunner.new(klass, columns, namespace, generate_model).run
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# ScaffoldRunner: handles the actual file generation
|
24
|
+
class ScaffoldRunner
|
25
|
+
def initialize(model_name, columns, namespace, generate_model)
|
26
|
+
@model_name = model_name
|
27
|
+
@columns = columns
|
28
|
+
@namespace = namespace
|
29
|
+
@generate_model = generate_model
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
generate_model_file if @generate_model
|
34
|
+
generate_file("repository")
|
35
|
+
generate_file("service")
|
36
|
+
generate_file("blueprint")
|
37
|
+
generate_file("controller")
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_model_file
|
41
|
+
system("rails generate model #{@model_name} #{column_args.join(" ")}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def column_args
|
45
|
+
@columns.map { |col| "#{col.name}:#{col.sql_type}" unless col.name == "id" }.compact
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate_file(type) # rubocop:disable Metrics/MethodLength
|
49
|
+
require "erb"
|
50
|
+
|
51
|
+
template_path = File.expand_path("../generators/domino/templates/#{type}.rb.tt", __FILE__)
|
52
|
+
raise "Missing template: #{template_path}" unless File.exist?(template_path)
|
53
|
+
|
54
|
+
content = ERB.new(File.read(template_path)).result(binding)
|
55
|
+
|
56
|
+
puts "Generating #{type} for #{@model_name}"
|
57
|
+
|
58
|
+
folder = case type
|
59
|
+
when "blueprint" then "app/mappers"
|
60
|
+
when "controller" then "app/controllers"
|
61
|
+
when "repository" then "app/repositories"
|
62
|
+
when "service" then "app/services"
|
63
|
+
else "app/#{type}s"
|
64
|
+
end
|
65
|
+
|
66
|
+
filename = case type
|
67
|
+
when "controller"
|
68
|
+
"#{@model_name.underscore.pluralize}_controller.rb"
|
69
|
+
else
|
70
|
+
"#{@model_name.underscore}_#{type}.rb"
|
71
|
+
end
|
72
|
+
|
73
|
+
FileUtils.mkdir_p(folder)
|
74
|
+
File.write(File.join(folder, filename), content)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/domino.rb
ADDED
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-domino
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kiebor81
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-07-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: blueprinter
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.30'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.30'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-auto_inject
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dry-container
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '6.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '6.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- lib/domino.rb
|
90
|
+
- lib/domino/base_repository.rb
|
91
|
+
- lib/domino/base_service.rb
|
92
|
+
- lib/domino/generators/domino/domino_generator.rb
|
93
|
+
- lib/domino/generators/domino/templates/blueprint.rb.tt
|
94
|
+
- lib/domino/generators/domino/templates/controller.rb.tt
|
95
|
+
- lib/domino/generators/domino/templates/repository.rb.tt
|
96
|
+
- lib/domino/generators/domino/templates/service.rb.tt
|
97
|
+
- lib/domino/scaffolder.rb
|
98
|
+
- lib/domino/version.rb
|
99
|
+
homepage: https://github.com/kiebor81/rails-domino
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '3.0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubygems_version: 3.5.17
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Domain-first service and repository scaffold for Rails. Enforces DDD architecture
|
122
|
+
with Blueprinter and Dry-rb libraries
|
123
|
+
test_files: []
|