ecs_on_rails 0.2.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 +7 -0
- data/CHANGELOG.md +88 -0
- data/LICENSE.txt +21 -0
- data/README.md +128 -0
- data/lib/ecs_on_rails.rb +10 -0
- data/lib/ecs_rails/component.rb +68 -0
- data/lib/ecs_rails/config.rb +31 -0
- data/lib/ecs_rails/dsl.rb +516 -0
- data/lib/ecs_rails/entity.rb +233 -0
- data/lib/ecs_rails/errors.rb +28 -0
- data/lib/ecs_rails/lazy.rb +244 -0
- data/lib/ecs_rails/preloading.rb +84 -0
- data/lib/ecs_rails/presence.rb +125 -0
- data/lib/ecs_rails/querying.rb +102 -0
- data/lib/ecs_rails/railtie.rb +14 -0
- data/lib/ecs_rails/registry.rb +152 -0
- data/lib/ecs_rails/relationships.rb +316 -0
- data/lib/ecs_rails/validations.rb +150 -0
- data/lib/ecs_rails/version.rb +5 -0
- data/lib/ecs_rails.rb +47 -0
- data/lib/generators/ecs_rails/component/component_generator.rb +101 -0
- data/lib/generators/ecs_rails/component/templates/component_spec.rb.tt +16 -0
- data/lib/generators/ecs_rails/component/templates/migration.rb.tt +25 -0
- data/lib/generators/ecs_rails/component/templates/model.rb.tt +13 -0
- data/lib/generators/ecs_rails/install/install_generator.rb +83 -0
- data/lib/generators/ecs_rails/install/templates/application_component.rb.tt +16 -0
- data/lib/generators/ecs_rails/install/templates/application_entity.rb.tt +15 -0
- data/lib/generators/ecs_rails/install/templates/initializer.rb.tt +19 -0
- data/lib/generators/ecs_rails/install/templates/migration.rb.tt +20 -0
- data/lib/generators/ecs_rails/relationship/relationship_generator.rb +94 -0
- data/lib/generators/ecs_rails/relationship/templates/migration.rb.tt +32 -0
- metadata +138 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# active_record must be required explicitly: rails/generators/active_record/
|
|
4
|
+
# migration references ActiveRecord::Migration and ActiveRecord::VERSION but
|
|
5
|
+
# does not load them itself. A host Rails app happens to have ActiveRecord
|
|
6
|
+
# loaded already, so omitting this only breaks in isolation — which is exactly
|
|
7
|
+
# where it is hardest to notice.
|
|
8
|
+
require "active_record"
|
|
9
|
+
require "rails/generators/named_base"
|
|
10
|
+
require "rails/generators/active_record/migration"
|
|
11
|
+
|
|
12
|
+
# ADR-0010: the generator reads EcsRails.config to place its files and to fill in
|
|
13
|
+
# the initializer. Require the library explicitly so the generator stands on its
|
|
14
|
+
# own requires — a clean `rails g` process must reach EcsRails.config without
|
|
15
|
+
# depending on some other file having loaded it first (see RFC-0008's isolation
|
|
16
|
+
# note and spec/generators/generator_isolation_spec.rb).
|
|
17
|
+
require "ecs_rails"
|
|
18
|
+
|
|
19
|
+
module EcsRails
|
|
20
|
+
module Generators
|
|
21
|
+
# `rails g ecs_rails:install`
|
|
22
|
+
#
|
|
23
|
+
# Implements RFC-0008. Emits the `entities` migration and the two abstract
|
|
24
|
+
# base classes a host app subclasses from. The migration mirrors
|
|
25
|
+
# docs/architecture.md §2 exactly — if the two ever disagree, the
|
|
26
|
+
# architecture document wins.
|
|
27
|
+
#
|
|
28
|
+
# Inherits from Base rather than NamedBase: install takes no NAME argument.
|
|
29
|
+
class InstallGenerator < Rails::Generators::Base
|
|
30
|
+
include ActiveRecord::Generators::Migration
|
|
31
|
+
|
|
32
|
+
source_root File.expand_path("templates", __dir__)
|
|
33
|
+
|
|
34
|
+
desc "Creates the entities migration and the ApplicationEntity / " \
|
|
35
|
+
"ApplicationComponent base classes."
|
|
36
|
+
|
|
37
|
+
def create_migration_file
|
|
38
|
+
migration_template(
|
|
39
|
+
"migration.rb.tt",
|
|
40
|
+
File.join(db_migrate_path, "ecs_rails_create_entities.rb")
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# ADR-0010: base classes land under the configured layout —
|
|
45
|
+
# ApplicationEntity at entities_path, ApplicationComponent at
|
|
46
|
+
# components_path (entities_path/components).
|
|
47
|
+
def create_base_models
|
|
48
|
+
template "application_entity.rb.tt",
|
|
49
|
+
File.join(EcsRails.config.entities_path, "application_entity.rb")
|
|
50
|
+
template "application_component.rb.tt",
|
|
51
|
+
File.join(EcsRails.config.components_path, "application_component.rb")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# ADR-0010: the generated initializer both records the chosen layout (so
|
|
55
|
+
# ecs_rails:component and the app agree on it) and collapses the nested
|
|
56
|
+
# components directory, so Zeitwerk maps app/entities/components/name.rb to
|
|
57
|
+
# the top-level `Name` rather than `Components::Name`.
|
|
58
|
+
#
|
|
59
|
+
# An initializer — not application.rb, not the gem's Railtie — is the right
|
|
60
|
+
# home for the collapse: it runs before eager_load under both lazy and
|
|
61
|
+
# eager modes, and it does not read entities_path before app initializers
|
|
62
|
+
# have had their chance to set it. See ADR-0010 "How it works".
|
|
63
|
+
def create_initializer
|
|
64
|
+
template "initializer.rb.tt", "config/initializers/ecs_rails.rb"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# The literal path written into the generated initializer's
|
|
70
|
+
# `entities_path =` line. Reflects whatever entities_path is at generation
|
|
71
|
+
# time, so a pre-configured layout carries through into the initializer.
|
|
72
|
+
def entities_path
|
|
73
|
+
EcsRails.config.entities_path
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# The `ActiveRecord::Migration[x.y]` version stamp, tracking whatever
|
|
77
|
+
# ActiveRecord the host app is actually running.
|
|
78
|
+
def migration_version
|
|
79
|
+
"#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The base class for every component in this application.
|
|
4
|
+
#
|
|
5
|
+
# A component is an ordinary ActiveRecord model that owns one table and belongs
|
|
6
|
+
# to exactly one entity. It may hold behaviour as well as data, and it must
|
|
7
|
+
# never reference an entity subclass.
|
|
8
|
+
#
|
|
9
|
+
# Generate one with:
|
|
10
|
+
#
|
|
11
|
+
# rails g ecs_rails:component Email address:string verified:boolean
|
|
12
|
+
#
|
|
13
|
+
# See docs/architecture.md §1.
|
|
14
|
+
class ApplicationComponent < EcsRails::Component
|
|
15
|
+
self.abstract_class = true
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The base class for every entity in this application.
|
|
4
|
+
#
|
|
5
|
+
# An entity is an immutable identity row: a UUID and a `model` discriminator,
|
|
6
|
+
# and nothing else. All state lives in components.
|
|
7
|
+
#
|
|
8
|
+
# class User < ApplicationEntity
|
|
9
|
+
# component Email
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# See docs/architecture.md §1.
|
|
13
|
+
class ApplicationEntity < EcsRails::Entity
|
|
14
|
+
self.abstract_class = true
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# ECS Rails directory layout (ADR-0010).
|
|
4
|
+
#
|
|
5
|
+
# entities_path is the single knob: entities live here, components live in its
|
|
6
|
+
# `components` subdirectory. Set it to "app/models" to restore the old
|
|
7
|
+
# single-directory layout (no collapse is needed then, since nothing nests).
|
|
8
|
+
EcsRails.configure do |config|
|
|
9
|
+
config.entities_path = "<%= entities_path %>"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Rails auto-adds every immediate subdirectory of app/ as an autoload root, so
|
|
13
|
+
# app/entities works for free. The nested components/ directory is the exception:
|
|
14
|
+
# without this, Zeitwerk would namespace it as Components::Name. `collapse` makes
|
|
15
|
+
# the components/ segment transparent, exactly as Rails does for app/models/
|
|
16
|
+
# concerns — so app/entities/components/name.rb resolves to the top-level `Name`.
|
|
17
|
+
Rails.autoloaders.main.collapse(
|
|
18
|
+
Rails.root.join(EcsRails.config.entities_path, "components")
|
|
19
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Creates the single `entities` table every ECS Rails entity shares.
|
|
4
|
+
# See docs/architecture.md §2 and docs/adr/0002-single-entities-table.md.
|
|
5
|
+
class EcsRailsCreateEntities < ActiveRecord::Migration[<%= migration_version %>]
|
|
6
|
+
def change
|
|
7
|
+
# gen_random_uuid() lives in pgcrypto on PostgreSQL < 13; enabling it is
|
|
8
|
+
# harmless on 13+, where the function is built in.
|
|
9
|
+
enable_extension "pgcrypto" unless extension_enabled?("pgcrypto")
|
|
10
|
+
|
|
11
|
+
create_table :entities, id: :uuid, default: -> { "gen_random_uuid()" } do |t|
|
|
12
|
+
# The entity subclass discriminator, e.g. "users". Indexed because
|
|
13
|
+
# User.all compiles to WHERE model = 'users'.
|
|
14
|
+
t.string :model, null: false, index: true
|
|
15
|
+
t.datetime :created_at, null: false
|
|
16
|
+
# No updated_at — an entity is written once and never changes.
|
|
17
|
+
# See RFC-0001 and docs/architecture.md §1.
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# See the note in component_generator.rb: rails/generators/active_record/migration
|
|
4
|
+
# references ActiveRecord::Migration without loading it, so these are required
|
|
5
|
+
# explicitly for load-isolation (generator_isolation_spec.rb).
|
|
6
|
+
require "active_record"
|
|
7
|
+
require "rails/generators/named_base"
|
|
8
|
+
require "rails/generators/active_record/migration"
|
|
9
|
+
|
|
10
|
+
# ADR-0010: the generator reads EcsRails.config. Require the library explicitly so
|
|
11
|
+
# the generator stands on its own requires (RFC-0008's isolation note).
|
|
12
|
+
require "ecs_rails"
|
|
13
|
+
|
|
14
|
+
module EcsRails
|
|
15
|
+
module Generators
|
|
16
|
+
# `rails g ecs_rails:relationship OWNER name:Target`
|
|
17
|
+
#
|
|
18
|
+
# rails g ecs_rails:relationship Post author:User
|
|
19
|
+
#
|
|
20
|
+
# Implements RFC-0012 / ADR-0013. Unlike the component generator, this emits
|
|
21
|
+
# ONLY a migration — `relates_to` defines the backing component dynamically,
|
|
22
|
+
# so there is no model file to write. It prints a reminder to add the
|
|
23
|
+
# `relates_to` line to the entity.
|
|
24
|
+
#
|
|
25
|
+
# The migration creates the owner-scoped backing table `post_authors`:
|
|
26
|
+
# - uuid PK,
|
|
27
|
+
# - entity_id: not-null, UNIQUE index, ON DELETE CASCADE FK to entities —
|
|
28
|
+
# the owner side (a post has at most one author; destroying the post
|
|
29
|
+
# destroys the link),
|
|
30
|
+
# - author_id: indexed, ON DELETE **NULLIFY** FK to entities — the target
|
|
31
|
+
# side (destroying the target nullifies, does not cascade to the owner),
|
|
32
|
+
# - timestamps.
|
|
33
|
+
#
|
|
34
|
+
# The single `name:Target` argument does not fit Rails' GeneratedAttribute
|
|
35
|
+
# (there is no `:Target` column type), so it is parsed by hand — see
|
|
36
|
+
# #parse_relationship!.
|
|
37
|
+
class RelationshipGenerator < Rails::Generators::NamedBase
|
|
38
|
+
include ActiveRecord::Generators::Migration
|
|
39
|
+
|
|
40
|
+
source_root File.expand_path("templates", __dir__)
|
|
41
|
+
|
|
42
|
+
argument :relationship, type: :string, banner: "name:Target"
|
|
43
|
+
|
|
44
|
+
desc "Creates the migration for a relationship's backing table (no model)."
|
|
45
|
+
|
|
46
|
+
def create_migration_file
|
|
47
|
+
parse_relationship!
|
|
48
|
+
migration_template(
|
|
49
|
+
"migration.rb.tt",
|
|
50
|
+
File.join(db_migrate_path, "create_#{backing_table_name}.rb")
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# RFC-0012: no component file. The DSL defines the backing component; the
|
|
55
|
+
# developer only has to declare the relationship on the entity.
|
|
56
|
+
def print_relates_to_reminder
|
|
57
|
+
entity_path = File.join(EcsRails.config.entities_path, class_path, "#{file_name}.rb")
|
|
58
|
+
say "Add the relationship to #{entity_path}:", :green
|
|
59
|
+
say " relates_to :#{relation_name}, #{target_class_name}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# Splits the `name:Target` argument. `file_name` (from NamedBase) is the
|
|
65
|
+
# OWNER, e.g. "post"; `relationship` is "author:User".
|
|
66
|
+
def parse_relationship!
|
|
67
|
+
@relation_name, @target_class_name = relationship.split(":", 2)
|
|
68
|
+
|
|
69
|
+
return unless @relation_name.to_s.empty? || @target_class_name.to_s.empty?
|
|
70
|
+
|
|
71
|
+
raise Thor::Error,
|
|
72
|
+
"expected OWNER name:Target, e.g. " \
|
|
73
|
+
"`rails g ecs_rails:relationship Post author:User` (got #{relationship.inspect})"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
attr_reader :relation_name, :target_class_name
|
|
77
|
+
|
|
78
|
+
# The owner-scoped backing table: #{owner.singular}_#{relation.plural} —
|
|
79
|
+
# `post_authors`. Mirrors the derivation in EcsRails::Relationships.
|
|
80
|
+
def backing_table_name
|
|
81
|
+
"#{singular_table_name}_#{relation_name.pluralize}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The target FK column: `author_id`. Mirrors EcsRails::Relationships.
|
|
85
|
+
def target_foreign_key
|
|
86
|
+
"#{relation_name}_id"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def migration_version
|
|
90
|
+
"#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Creates the <%= backing_table_name %> relationship backing table
|
|
4
|
+
# (RFC-0012 / ADR-0013). This is what `relates_to :<%= relation_name %>,
|
|
5
|
+
# <%= target_class_name %>` reads; there is no relationship component file — the
|
|
6
|
+
# DSL defines the backing component dynamically.
|
|
7
|
+
#
|
|
8
|
+
# The owner side (entity_id) and the target side (<%= target_foreign_key %>) are
|
|
9
|
+
# deliberately asymmetric:
|
|
10
|
+
# - entity_id: not-null, UNIQUE (ADR-0005: at most one per owner), ON DELETE
|
|
11
|
+
# CASCADE — destroying the owner destroys the link.
|
|
12
|
+
# - <%= target_foreign_key %>: nullable, ON DELETE NULLIFY — destroying the
|
|
13
|
+
# TARGET nullifies the link, it does NOT cascade to the owner.
|
|
14
|
+
class Create<%= backing_table_name.camelize %> < ActiveRecord::Migration[<%= migration_version %>]
|
|
15
|
+
def change
|
|
16
|
+
create_table :<%= backing_table_name %>, id: :uuid, default: -> { "gen_random_uuid()" } do |t|
|
|
17
|
+
t.uuid :entity_id, null: false
|
|
18
|
+
t.uuid :<%= target_foreign_key %>, default: nil
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# ADR-0005: at most one relationship row per owner entity.
|
|
23
|
+
add_index :<%= backing_table_name %>, :entity_id, unique: true
|
|
24
|
+
|
|
25
|
+
# Destroying the owner destroys the link, at the database level.
|
|
26
|
+
add_foreign_key :<%= backing_table_name %>, :entities, column: :entity_id, on_delete: :cascade
|
|
27
|
+
|
|
28
|
+
# Destroying the TARGET nullifies the link — it does not cascade to the owner.
|
|
29
|
+
add_index :<%= backing_table_name %>, :<%= target_foreign_key %>
|
|
30
|
+
add_foreign_key :<%= backing_table_name %>, :entities, column: :<%= target_foreign_key %>, on_delete: :nullify
|
|
31
|
+
end
|
|
32
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ecs_on_rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jason Hutchens
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.1'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: activesupport
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '7.1'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '9.0'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '7.1'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '9.0'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: railties
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '7.1'
|
|
59
|
+
- - "<"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '9.0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '7.1'
|
|
69
|
+
- - "<"
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '9.0'
|
|
72
|
+
description: |
|
|
73
|
+
ECS Rails extends ActiveRecord with an Entity-Component-System persistence
|
|
74
|
+
architecture inspired by Flecs, while remaining idiomatic Rails. Entities
|
|
75
|
+
are lightweight identity records composed from reusable, lazily persisted
|
|
76
|
+
components that encapsulate both data and behaviour.
|
|
77
|
+
email:
|
|
78
|
+
- jasonhutchens@gmail.com
|
|
79
|
+
executables: []
|
|
80
|
+
extensions: []
|
|
81
|
+
extra_rdoc_files: []
|
|
82
|
+
files:
|
|
83
|
+
- CHANGELOG.md
|
|
84
|
+
- LICENSE.txt
|
|
85
|
+
- README.md
|
|
86
|
+
- lib/ecs_on_rails.rb
|
|
87
|
+
- lib/ecs_rails.rb
|
|
88
|
+
- lib/ecs_rails/component.rb
|
|
89
|
+
- lib/ecs_rails/config.rb
|
|
90
|
+
- lib/ecs_rails/dsl.rb
|
|
91
|
+
- lib/ecs_rails/entity.rb
|
|
92
|
+
- lib/ecs_rails/errors.rb
|
|
93
|
+
- lib/ecs_rails/lazy.rb
|
|
94
|
+
- lib/ecs_rails/preloading.rb
|
|
95
|
+
- lib/ecs_rails/presence.rb
|
|
96
|
+
- lib/ecs_rails/querying.rb
|
|
97
|
+
- lib/ecs_rails/railtie.rb
|
|
98
|
+
- lib/ecs_rails/registry.rb
|
|
99
|
+
- lib/ecs_rails/relationships.rb
|
|
100
|
+
- lib/ecs_rails/validations.rb
|
|
101
|
+
- lib/ecs_rails/version.rb
|
|
102
|
+
- lib/generators/ecs_rails/component/component_generator.rb
|
|
103
|
+
- lib/generators/ecs_rails/component/templates/component_spec.rb.tt
|
|
104
|
+
- lib/generators/ecs_rails/component/templates/migration.rb.tt
|
|
105
|
+
- lib/generators/ecs_rails/component/templates/model.rb.tt
|
|
106
|
+
- lib/generators/ecs_rails/install/install_generator.rb
|
|
107
|
+
- lib/generators/ecs_rails/install/templates/application_component.rb.tt
|
|
108
|
+
- lib/generators/ecs_rails/install/templates/application_entity.rb.tt
|
|
109
|
+
- lib/generators/ecs_rails/install/templates/initializer.rb.tt
|
|
110
|
+
- lib/generators/ecs_rails/install/templates/migration.rb.tt
|
|
111
|
+
- lib/generators/ecs_rails/relationship/relationship_generator.rb
|
|
112
|
+
- lib/generators/ecs_rails/relationship/templates/migration.rb.tt
|
|
113
|
+
homepage: https://github.com/kranzky/ecs_rails
|
|
114
|
+
licenses:
|
|
115
|
+
- MIT
|
|
116
|
+
metadata:
|
|
117
|
+
source_code_uri: https://github.com/kranzky/ecs_rails
|
|
118
|
+
changelog_uri: https://github.com/kranzky/ecs_rails/blob/main/CHANGELOG.md
|
|
119
|
+
bug_tracker_uri: https://github.com/kranzky/ecs_rails/issues
|
|
120
|
+
rubygems_mfa_required: 'true'
|
|
121
|
+
rdoc_options: []
|
|
122
|
+
require_paths:
|
|
123
|
+
- lib
|
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - ">="
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: 3.2.0
|
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
|
+
requirements:
|
|
131
|
+
- - ">="
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '0'
|
|
134
|
+
requirements: []
|
|
135
|
+
rubygems_version: 4.0.17
|
|
136
|
+
specification_version: 4
|
|
137
|
+
summary: An Entity-Component-System reimagining of ActiveRecord.
|
|
138
|
+
test_files: []
|