rails_templatable 0.1.1 → 0.1.2
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 +4 -4
- data/README.md +111 -77
- data/app/models/concerns/rails_templatable/has_template.rb +12 -0
- data/app/models/rails_templatable/template.rb +10 -13
- data/db/migrate/20250207000000_create_rails_templatable_tables.rb +9 -16
- data/lib/rails_templatable/version.rb +1 -1
- data/llms.txt +195 -226
- metadata +6 -11
- data/app/assets/stylesheets/rails_templatable/application.css +0 -15
- data/app/controllers/rails_templatable/application_controller.rb +0 -4
- data/app/helpers/rails_templatable/application_helper.rb +0 -4
- data/app/jobs/rails_templatable/application_job.rb +0 -4
- data/app/mailers/rails_templatable/application_mailer.rb +0 -6
- data/app/models/concerns/rails_templatable/has_templates.rb +0 -16
- data/app/models/rails_templatable/template_assignment.rb +0 -12
- data/app/views/layouts/rails_templatable/application.html.erb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1dc98737cfeeef797928b4f4c51fdeccbda1c4418a44232af9c856d7aab646e3
|
|
4
|
+
data.tar.gz: 97c2a8611ac44f12ca03b69461fa287e8da5ff978008af045087dfa56e915b18
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cebaebeec326a51b9e21cd53076845094f22f04b73f99afd672dc1eb2c9223ff01950698dcdc177d8b9923aae3e8dec64875f9e1e134a030ec80d4553a6171e8
|
|
7
|
+
data.tar.gz: 01357a634728a3243afa4e3919d6bd2c8333e5ec51a67f79194d27add6ae214f03ab4a835b3e2f2b14dbbd7f4a69eec5463f4917da90b421752f917e35527fb9
|
data/README.md
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# RailsTemplatable
|
|
2
2
|
|
|
3
|
-
A lightweight Rails Engine that enables any ActiveRecord model to
|
|
3
|
+
A lightweight Rails Engine that enables any ActiveRecord model to use predefined templates for content management. Built with a simple one-to-many relationship, allowing each model instance to have one template while templates can be reused across multiple instances.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🎯 **
|
|
7
|
+
- 🎯 **Simple 1:N Relationship** - Each record has one template, templates can be reused
|
|
8
8
|
- 📝 **Multiple Content Formats** - Support for HTML, Markdown, and plain text
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- 🔒 **Database Constraints** - Unique constraints at database level
|
|
9
|
+
- 🏷️ **Flexible Categories** - Pre-defined categories (feature_request, bug_report, etc.) or custom
|
|
10
|
+
- 🔗 **Direct Foreign Key** - No join table needed, cleaner database schema
|
|
12
11
|
- 🚀 **Easy Integration** - Simple concern-based inclusion
|
|
13
12
|
|
|
14
13
|
## Installation
|
|
@@ -26,54 +25,90 @@ $ bin/rails railties:install:migrations FROM=rails_templatable
|
|
|
26
25
|
$ bin/rails db:migrate
|
|
27
26
|
```
|
|
28
27
|
|
|
28
|
+
For each model that will use templates, add a foreign key:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
add_reference :posts, :template,
|
|
32
|
+
foreign_key: { to_table: :rails_templatable_templates },
|
|
33
|
+
index: false
|
|
34
|
+
```
|
|
35
|
+
|
|
29
36
|
## Quick Start
|
|
30
37
|
|
|
31
38
|
### 1. Enable templates in your models
|
|
32
39
|
|
|
33
40
|
```ruby
|
|
34
41
|
class Post < ApplicationRecord
|
|
35
|
-
include RailsTemplatable::
|
|
42
|
+
include RailsTemplatable::HasTemplate
|
|
36
43
|
end
|
|
37
44
|
|
|
38
45
|
class WorkLog < ApplicationRecord
|
|
39
|
-
include RailsTemplatable::
|
|
46
|
+
include RailsTemplatable::HasTemplate
|
|
40
47
|
end
|
|
41
48
|
```
|
|
42
49
|
|
|
43
50
|
### 2. Create templates
|
|
44
51
|
|
|
45
52
|
```ruby
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
category: "
|
|
49
|
-
content: "
|
|
50
|
-
content_format: :
|
|
53
|
+
# Feature request template
|
|
54
|
+
feature_template = RailsTemplatable::Template.create!(
|
|
55
|
+
category: "feature_request",
|
|
56
|
+
content: "# Feature Request\n\n## Description\n\n## Acceptance Criteria",
|
|
57
|
+
content_format: :markdown
|
|
51
58
|
)
|
|
52
59
|
|
|
53
|
-
#
|
|
54
|
-
|
|
55
|
-
category: "
|
|
56
|
-
content: "
|
|
60
|
+
# Bug report template
|
|
61
|
+
bug_template = RailsTemplatable::Template.create!(
|
|
62
|
+
category: "bug_report",
|
|
63
|
+
content: "## Bug Description\n\n## Steps to Reproduce\n\n## Expected Behavior",
|
|
57
64
|
content_format: :markdown
|
|
58
65
|
)
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
### 3.
|
|
68
|
+
### 3. Assign templates to records
|
|
62
69
|
|
|
63
70
|
```ruby
|
|
64
|
-
post = Post.create(
|
|
71
|
+
post = Post.create!(
|
|
72
|
+
title: "Add user authentication",
|
|
73
|
+
content: "Implement OAuth2 login",
|
|
74
|
+
template: feature_template
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# View template
|
|
78
|
+
post.template.category # => "feature_request"
|
|
79
|
+
post.template.content # => "# Feature Request..."
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Template Categories
|
|
83
|
+
|
|
84
|
+
Common template categories included:
|
|
85
|
+
|
|
86
|
+
| Category | Description |
|
|
87
|
+
|----------|-------------|
|
|
88
|
+
| `feature_request` | Feature requests |
|
|
89
|
+
| `bug_report` | Bug reports |
|
|
90
|
+
| `tech_improvement` | Technical improvements |
|
|
91
|
+
| `meeting_note` | Meeting notes |
|
|
92
|
+
| `api_design` | API designs |
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
post.templates << email_template
|
|
68
|
-
post.templates << doc_template
|
|
94
|
+
You can create any custom category as needed.
|
|
69
95
|
|
|
70
|
-
|
|
71
|
-
|
|
96
|
+
## Relationship Model
|
|
97
|
+
|
|
98
|
+
**One-to-Many (1:N)**
|
|
99
|
+
- One Post/WorkLog instance → One Template
|
|
100
|
+
- One Template → Many instances
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
```
|
|
104
|
+
Post 1 → Template A (feature_request)
|
|
105
|
+
Post 2 → Template B (bug_report)
|
|
106
|
+
Post 3 → Template A (feature_request) # Reusable
|
|
72
107
|
```
|
|
73
108
|
|
|
74
109
|
## Content Formats
|
|
75
110
|
|
|
76
|
-
|
|
111
|
+
Three content formats are supported:
|
|
77
112
|
|
|
78
113
|
- `html` (0) - HTML content
|
|
79
114
|
- `markdown` (1) - Markdown content
|
|
@@ -87,6 +122,22 @@ RailsTemplatable::Template.create!(
|
|
|
87
122
|
)
|
|
88
123
|
```
|
|
89
124
|
|
|
125
|
+
## Query Examples
|
|
126
|
+
|
|
127
|
+
```ruby
|
|
128
|
+
# Get a record's template
|
|
129
|
+
post.template
|
|
130
|
+
|
|
131
|
+
# Query by category
|
|
132
|
+
Post.joins(:template).where(rails_templatable_templates: { category: 'feature_request' })
|
|
133
|
+
|
|
134
|
+
# Get all records using a specific template
|
|
135
|
+
Post.where(template: feature_template)
|
|
136
|
+
|
|
137
|
+
# Query by content format
|
|
138
|
+
Post.joins(:template).where(rails_templatable_templates: { content_format: 1 })
|
|
139
|
+
```
|
|
140
|
+
|
|
90
141
|
## Database Schema
|
|
91
142
|
|
|
92
143
|
### rails_templatable_templates
|
|
@@ -99,41 +150,49 @@ RailsTemplatable::Template.create!(
|
|
|
99
150
|
| `created_at` | datetime | Creation timestamp |
|
|
100
151
|
| `updated_at` | datetime | Update timestamp |
|
|
101
152
|
|
|
102
|
-
###
|
|
153
|
+
### Target models (e.g., posts)
|
|
154
|
+
|
|
155
|
+
Add `template_id` foreign key:
|
|
103
156
|
|
|
104
157
|
| Column | Type | Description |
|
|
105
158
|
|--------|------|-------------|
|
|
106
|
-
| `template_id` | integer | Foreign key to
|
|
107
|
-
| `templatable_id` | integer | Polymorphic foreign key ID |
|
|
108
|
-
| `templatable_type` | string | Polymorphic foreign key type |
|
|
109
|
-
| `created_at` | datetime | Creation timestamp |
|
|
110
|
-
| `updated_at` | datetime | Update timestamp |
|
|
159
|
+
| `template_id` | integer | Foreign key to rails_templatable_templates |
|
|
111
160
|
|
|
112
161
|
## Advanced Usage
|
|
113
162
|
|
|
114
|
-
###
|
|
163
|
+
### Change template
|
|
115
164
|
|
|
116
165
|
```ruby
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
# Get all templates used on a specific model class
|
|
121
|
-
RailsTemplatable::Template.for_model(Post)
|
|
166
|
+
# Assigning a new template replaces the old one
|
|
167
|
+
post.update(template: bug_template)
|
|
168
|
+
post.template.category # => "bug_report"
|
|
122
169
|
```
|
|
123
170
|
|
|
124
|
-
###
|
|
171
|
+
### Remove template
|
|
125
172
|
|
|
126
173
|
```ruby
|
|
127
|
-
|
|
128
|
-
post.
|
|
174
|
+
post.update(template: nil)
|
|
175
|
+
post.template # => nil
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Assign template after creation
|
|
129
179
|
|
|
130
|
-
|
|
131
|
-
post.
|
|
180
|
+
```ruby
|
|
181
|
+
post = Post.create(title: "New post")
|
|
182
|
+
post.update(template: feature_template)
|
|
132
183
|
```
|
|
133
184
|
|
|
134
|
-
##
|
|
185
|
+
## Migration Example
|
|
135
186
|
|
|
136
|
-
|
|
187
|
+
```ruby
|
|
188
|
+
class AddTemplateToPosts < ActiveRecord::Migration[6.0]
|
|
189
|
+
def change
|
|
190
|
+
add_reference :posts, :template,
|
|
191
|
+
foreign_key: { to_table: :rails_templatable_templates },
|
|
192
|
+
index: false
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
```
|
|
137
196
|
|
|
138
197
|
## Development
|
|
139
198
|
|
|
@@ -144,45 +203,20 @@ cd test/dummy
|
|
|
144
203
|
ruby test_templatable.rb
|
|
145
204
|
```
|
|
146
205
|
|
|
147
|
-
### Database schema
|
|
148
|
-
|
|
149
|
-
After running migrations, your schema will include:
|
|
150
|
-
|
|
151
|
-
```ruby
|
|
152
|
-
create_table "rails_templatable_templates" do |t|
|
|
153
|
-
t.string "category", null: false
|
|
154
|
-
t.text "content"
|
|
155
|
-
t.integer "content_format", default: 2, null: false
|
|
156
|
-
t.index ["category"], name: "index_rails_templatable_templates_on_category"
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
create_table "rails_templatable_assignments" do |t|
|
|
160
|
-
t.integer "template_id", null: false
|
|
161
|
-
t.string "templatable_type", null: false
|
|
162
|
-
t.integer "templatable_id", null: false
|
|
163
|
-
t.index ["template_id", "templatable_type", "templatable_id"],
|
|
164
|
-
name: "index_templatable_assignments", unique: true
|
|
165
|
-
end
|
|
166
|
-
```
|
|
167
|
-
|
|
168
206
|
## Architecture
|
|
169
207
|
|
|
170
|
-
|
|
208
|
+
- **Direct Foreign Key** - No join table needed
|
|
209
|
+
- **Simple & Clean** - One record = One template
|
|
210
|
+
- **Flexible** - Templates can be changed anytime
|
|
211
|
+
- **Efficient Queries** - Direct JOIN without intermediate table
|
|
171
212
|
|
|
172
|
-
|
|
173
|
-
- **Polymorphic associations** - Using `templatable` for flexible model associations
|
|
174
|
-
- **Concern-based inclusion** - Simple `include RailsTemplatable::HasTemplates` to enable
|
|
175
|
-
- **Database-level constraints** - Unique indexes prevent duplicate associations
|
|
213
|
+
## Comparison with N:N Design
|
|
176
214
|
|
|
177
|
-
|
|
215
|
+
If you need "one record has multiple templates", consider using a tag system or polymorphic many-to-many associations instead.
|
|
178
216
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
| Fields | name, description | category, content, content_format |
|
|
183
|
-
| Enum Support | No | Yes (content_format) |
|
|
184
|
-
| Polymorphic Name | assignable | templatable |
|
|
185
|
-
| Concern | HasBadges | HasTemplates |
|
|
217
|
+
## Why `category` instead of `type`?
|
|
218
|
+
|
|
219
|
+
We use `category` instead of `type` to avoid conflicts with Rails' Single Table Inheritance (STI) feature, which reserves the `type` column for storing class names.
|
|
186
220
|
|
|
187
221
|
## Future Enhancements
|
|
188
222
|
|
|
@@ -2,24 +2,21 @@ module RailsTemplatable
|
|
|
2
2
|
class Template < ApplicationRecord
|
|
3
3
|
self.table_name = "rails_templatable_templates"
|
|
4
4
|
|
|
5
|
-
has_many :assignments, class_name: "RailsTemplatable::TemplateAssignment", dependent: :destroy
|
|
6
|
-
|
|
7
5
|
enum :content_format, { html: 0, markdown: 1, txt: 2 }
|
|
8
6
|
|
|
9
7
|
validates :category, presence: true
|
|
10
8
|
validates :content, presence: true
|
|
11
9
|
validates :content_format, presence: true
|
|
12
10
|
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
end
|
|
11
|
+
# Note: This template can be referenced by any model that includes HasTemplate concern.
|
|
12
|
+
# Target models should define their own has_many relationship if needed.
|
|
13
|
+
#
|
|
14
|
+
# Example in target model:
|
|
15
|
+
# class Post < ApplicationRecord
|
|
16
|
+
# include RailsTemplatable::HasTemplate
|
|
17
|
+
#
|
|
18
|
+
# # Optional: define reverse association
|
|
19
|
+
# has_many :feature_posts, class_name: "Post", foreign_key: :template_id
|
|
20
|
+
# end
|
|
24
21
|
end
|
|
25
22
|
end
|
|
@@ -16,21 +16,14 @@ class CreateRailsTemplatableTables < ActiveRecord::Migration[6.0]
|
|
|
16
16
|
|
|
17
17
|
add_index :rails_templatable_templates, :category
|
|
18
18
|
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Custom composite index with short name
|
|
31
|
-
add_index :rails_templatable_assignments,
|
|
32
|
-
[:template_id, :templatable_type, :templatable_id],
|
|
33
|
-
unique: true,
|
|
34
|
-
name: "index_templatable_assignments"
|
|
19
|
+
# Note: No join table needed.
|
|
20
|
+
# Target models (posts, work_logs, etc.) should add their own template_id foreign key:
|
|
21
|
+
#
|
|
22
|
+
# add_reference :posts, :template,
|
|
23
|
+
# foreign_key: { to_table: :rails_templatable_templates },
|
|
24
|
+
# index: false
|
|
25
|
+
# add_reference :work_logs, :template,
|
|
26
|
+
# foreign_key: { to_table: :rails_templatable_templates },
|
|
27
|
+
# index: false
|
|
35
28
|
end
|
|
36
29
|
end
|
data/llms.txt
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Rails Templatable
|
|
2
2
|
|
|
3
|
-
> Rails Templatable is a lightweight, reusable Rails Engine that enables any ActiveRecord model to
|
|
3
|
+
> Rails Templatable is a lightweight, reusable Rails Engine that enables any ActiveRecord model to use predefined templates for content management via a simple one-to-many relationship.
|
|
4
4
|
|
|
5
5
|
It provides a clean, namespace-isolated way to add template functionality to your Rails applications without polluting your models or database schema. The engine uses standard Rails conventions and is fully compatible with Rails 6.0+.
|
|
6
6
|
|
|
7
7
|
**Important notes for AI agents:**
|
|
8
8
|
- This is a Rails Engine, not a mountable engine (no routes, controllers, or views)
|
|
9
9
|
- All models are namespaced under `RailsTemplatable` module
|
|
10
|
-
-
|
|
11
|
-
-
|
|
10
|
+
- Uses 1:N relationship (one record has one template, one template can have many records)
|
|
11
|
+
- No join table - uses direct foreign key `template_id` on target models
|
|
12
12
|
- Uses `category` instead of `type` to avoid Rails STI (Single Table Inheritance) conflicts
|
|
13
13
|
- Supports three content formats: HTML (0), Markdown (1), and TXT (2)
|
|
14
14
|
- The `content_format` field uses Rails enum with new syntax: `enum :content_format, { html: 0, markdown: 1, txt: 2 }`
|
|
@@ -17,18 +17,17 @@ It provides a clean, namespace-isolated way to add template functionality to you
|
|
|
17
17
|
|
|
18
18
|
- [GitHub Repository](https://github.com/afeiship/rails_templatable): Source code and issue tracking
|
|
19
19
|
- [README](README.md): Installation guide and basic usage examples
|
|
20
|
-
- [
|
|
20
|
+
- [Design Document](docs/01-design.md): Detailed design specifications
|
|
21
21
|
- [Usage Guide](docs/02-usage.md): Comprehensive usage examples
|
|
22
|
-
- [
|
|
22
|
+
- [Redesign Summary](docs/03-redesign-summary.md): Architecture redesign from N:N to 1:N
|
|
23
23
|
|
|
24
24
|
## Key Features
|
|
25
25
|
|
|
26
|
-
- **
|
|
27
|
-
- **Multiple Content Formats:** Support for HTML, Markdown, and plain text
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **Flexible Categories:** User-defined template categories (no hardcoded types)
|
|
26
|
+
- **Simple 1:N Relationship:** Each record has one template, templates can be reused
|
|
27
|
+
- **Multiple Content Formats:** Support for HTML, Markdown, and plain text
|
|
28
|
+
- **Flexible Categories:** User-defined template categories (feature_request, bug_report, etc.)
|
|
29
|
+
- **Direct Foreign Key:** No join table needed, cleaner database schema
|
|
30
|
+
- **Namespace Isolated:** All models under `RailsTemplatable` namespace
|
|
32
31
|
- **Rails 6.0+ Compatible:** Works with modern Rails versions (tested on Rails 8.1.2)
|
|
33
32
|
- **Zero Configuration:** Works out of the box after migration
|
|
34
33
|
|
|
@@ -47,79 +46,147 @@ rails railties:install:migrations FROM=rails_templatable
|
|
|
47
46
|
rails db:migrate
|
|
48
47
|
```
|
|
49
48
|
|
|
49
|
+
Add foreign key to each model that will use templates:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
add_reference :posts, :template,
|
|
53
|
+
foreign_key: { to_table: :rails_templatable_templates },
|
|
54
|
+
index: false
|
|
55
|
+
```
|
|
56
|
+
|
|
50
57
|
## Basic Usage
|
|
51
58
|
|
|
52
59
|
### Include the Concern
|
|
53
60
|
|
|
54
61
|
```ruby
|
|
55
62
|
class Post < ApplicationRecord
|
|
56
|
-
include RailsTemplatable::
|
|
63
|
+
include RailsTemplatable::HasTemplate
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
class WorkLog < ApplicationRecord
|
|
60
|
-
include RailsTemplatable::
|
|
67
|
+
include RailsTemplatable::HasTemplate
|
|
61
68
|
end
|
|
62
69
|
```
|
|
63
70
|
|
|
64
|
-
### Create
|
|
71
|
+
### Create Templates
|
|
65
72
|
|
|
66
73
|
```ruby
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
category: "
|
|
70
|
-
content: "
|
|
71
|
-
content_format: :
|
|
74
|
+
# Feature request template
|
|
75
|
+
feature_template = RailsTemplatable::Template.create!(
|
|
76
|
+
category: "feature_request",
|
|
77
|
+
content: "# Feature Request\n\n## Description\n\n## Acceptance Criteria",
|
|
78
|
+
content_format: :markdown
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Bug report template
|
|
82
|
+
bug_template = RailsTemplatable::Template.create!(
|
|
83
|
+
category: "bug_report",
|
|
84
|
+
content: "## Bug Description\n\n## Steps to Reproduce\n\n## Expected Behavior",
|
|
85
|
+
content_format: :markdown
|
|
72
86
|
)
|
|
73
87
|
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
category: "
|
|
77
|
-
content: "#
|
|
88
|
+
# Meeting note template
|
|
89
|
+
meeting_template = RailsTemplatable::Template.create!(
|
|
90
|
+
category: "meeting_note",
|
|
91
|
+
content: "# Meeting: {title}\n\nDate: {date}\n\n## Attendees\n\n## Agenda",
|
|
78
92
|
content_format: :markdown
|
|
79
93
|
)
|
|
80
94
|
|
|
81
|
-
#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
# Tech improvement template
|
|
96
|
+
tech_template = RailsTemplatable::Template.create!(
|
|
97
|
+
category: "tech_improvement",
|
|
98
|
+
content: "## Current State\n\n## Proposed Improvement\n\n## Benefits",
|
|
99
|
+
content_format: :markdown
|
|
100
|
+
)
|
|
85
101
|
|
|
86
|
-
#
|
|
87
|
-
|
|
102
|
+
# API design template
|
|
103
|
+
api_template = RailsTemplatable::Template.create!(
|
|
104
|
+
category: "api_design",
|
|
105
|
+
content: "## Endpoint\n\n## Request\n\n## Response",
|
|
106
|
+
content_format: :markdown
|
|
107
|
+
)
|
|
88
108
|
```
|
|
89
109
|
|
|
90
|
-
###
|
|
110
|
+
### Assign Templates to Records
|
|
91
111
|
|
|
92
112
|
```ruby
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
113
|
+
# Create with template
|
|
114
|
+
post = Post.create!(
|
|
115
|
+
title: "Add user authentication",
|
|
116
|
+
content: "Implement OAuth2",
|
|
117
|
+
template: feature_template
|
|
118
|
+
)
|
|
96
119
|
|
|
97
|
-
#
|
|
98
|
-
|
|
99
|
-
|
|
120
|
+
# Assign template later
|
|
121
|
+
work_log = WorkLog.create!(title: "Daily standup")
|
|
122
|
+
work_log.update(template: meeting_template)
|
|
100
123
|
|
|
101
|
-
#
|
|
102
|
-
post.
|
|
124
|
+
# View template
|
|
125
|
+
post.template.category # => "feature_request"
|
|
126
|
+
post.template.content # => "# Feature Request..."
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Query Templates
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
# Get a record's template
|
|
133
|
+
post.template
|
|
103
134
|
|
|
104
|
-
#
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
# Query by category
|
|
136
|
+
Post.joins(:template).where(rails_templatable_templates: { category: 'feature_request' })
|
|
137
|
+
|
|
138
|
+
# Get all records using a specific template
|
|
139
|
+
Post.where(template: feature_template)
|
|
140
|
+
|
|
141
|
+
# Query by content format
|
|
142
|
+
Post.joins(:template).where(rails_templatable_templates: { content_format: 1 })
|
|
108
143
|
```
|
|
109
144
|
|
|
110
|
-
###
|
|
145
|
+
### Change Template
|
|
111
146
|
|
|
112
147
|
```ruby
|
|
113
|
-
#
|
|
114
|
-
post.
|
|
148
|
+
# Assigning a new template replaces the old one
|
|
149
|
+
post.update(template: bug_template)
|
|
150
|
+
post.template.category # => "bug_report"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Remove Template
|
|
154
|
+
|
|
155
|
+
```ruby
|
|
156
|
+
post.update(template: nil)
|
|
157
|
+
post.template # => nil
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Template Categories
|
|
161
|
+
|
|
162
|
+
Common template categories:
|
|
115
163
|
|
|
116
|
-
|
|
117
|
-
|
|
164
|
+
| Category | Description |
|
|
165
|
+
|----------|-------------|
|
|
166
|
+
| `feature_request` | Feature requests |
|
|
167
|
+
| `bug_report` | Bug reports |
|
|
168
|
+
| `tech_improvement` | Technical improvements |
|
|
169
|
+
| `meeting_note` | Meeting notes |
|
|
170
|
+
| `api_design` | API designs |
|
|
171
|
+
|
|
172
|
+
Users can create any custom category.
|
|
173
|
+
|
|
174
|
+
## Relationship Model
|
|
175
|
+
|
|
176
|
+
**One-to-Many (1:N)**
|
|
177
|
+
- One Post/WorkLog instance → One Template
|
|
178
|
+
- One Template → Many instances
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
```
|
|
182
|
+
Post 1 → Template A (feature_request)
|
|
183
|
+
Post 2 → Template B (bug_report)
|
|
184
|
+
Post 3 → Template A (feature_request) # Reusable
|
|
118
185
|
```
|
|
119
186
|
|
|
120
187
|
## Database Schema
|
|
121
188
|
|
|
122
|
-
###
|
|
189
|
+
### rails_templatable_templates
|
|
123
190
|
|
|
124
191
|
```ruby
|
|
125
192
|
create_table :rails_templatable_templates do |t|
|
|
@@ -133,27 +200,22 @@ add_index :rails_templatable_templates, :category
|
|
|
133
200
|
```
|
|
134
201
|
|
|
135
202
|
**Field Details:**
|
|
136
|
-
- `category` (string) - User-defined template category
|
|
203
|
+
- `category` (string) - User-defined template category
|
|
137
204
|
- `content` (text) - Template content (static text, no variable replacement)
|
|
138
205
|
- `content_format` (integer) - Content format: 0=HTML, 1=Markdown, 2=TXT (default)
|
|
139
206
|
- Index on `category` for fast lookups
|
|
140
207
|
|
|
141
|
-
###
|
|
208
|
+
### Target Models (e.g., posts)
|
|
142
209
|
|
|
143
|
-
|
|
144
|
-
create_table :rails_templatable_assignments do |t|
|
|
145
|
-
t.references :template, null: false, foreign_key: { to_table: :rails_templatable_templates }
|
|
146
|
-
t.references :templatable, polymorphic: true, null: false
|
|
147
|
-
t.timestamps
|
|
148
|
-
end
|
|
210
|
+
Add `template_id` foreign key:
|
|
149
211
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
212
|
+
```ruby
|
|
213
|
+
add_reference :posts, :template,
|
|
214
|
+
foreign_key: { to_table: :rails_templatable_templates },
|
|
215
|
+
index: false
|
|
154
216
|
```
|
|
155
217
|
|
|
156
|
-
**Constraint:**
|
|
218
|
+
**Constraint:** Each record can have only one template (foreign key is single, not array).
|
|
157
219
|
|
|
158
220
|
## Content Formats
|
|
159
221
|
|
|
@@ -170,7 +232,12 @@ enum :content_format, {
|
|
|
170
232
|
**Usage:**
|
|
171
233
|
|
|
172
234
|
```ruby
|
|
173
|
-
#
|
|
235
|
+
# Query by format
|
|
236
|
+
post.template.html? # => true/false
|
|
237
|
+
post.template.markdown? # => true/false
|
|
238
|
+
post.template.txt? # => true/false
|
|
239
|
+
|
|
240
|
+
# Create different formats
|
|
174
241
|
html_template = RailsTemplatable::Template.create!(
|
|
175
242
|
category: "email",
|
|
176
243
|
content: "<h1>Welcome</h1>",
|
|
@@ -179,116 +246,19 @@ html_template = RailsTemplatable::Template.create!(
|
|
|
179
246
|
|
|
180
247
|
markdown_template = RailsTemplatable::Template.create!(
|
|
181
248
|
category: "docs",
|
|
182
|
-
content: "# Guide\n\nInstructions
|
|
249
|
+
content: "# Guide\n\nInstructions",
|
|
183
250
|
content_format: :markdown
|
|
184
251
|
)
|
|
185
|
-
|
|
186
|
-
txt_template = RailsTemplatable::Template.create!(
|
|
187
|
-
category: "notification",
|
|
188
|
-
content: "Simple text message",
|
|
189
|
-
content_format: :txt
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
# Query by format
|
|
193
|
-
post.templates.html # => [#<RailsTemplatable::Template content_format: 0>]
|
|
194
|
-
post.templates.markdown # => [#<RailsTemplatable::Template content_format: 1>]
|
|
195
|
-
post.templates.txt # => [#<RailsTemplatable::Template content_format: 2>]
|
|
196
252
|
```
|
|
197
253
|
|
|
198
254
|
## Available Methods
|
|
199
255
|
|
|
200
|
-
###
|
|
201
|
-
|
|
202
|
-
- `template.assigned_to(klass)` - Returns all records of the given class that have this template
|
|
203
|
-
```ruby
|
|
204
|
-
template.assigned_to(Post) # => [post1, post2]
|
|
205
|
-
template.assigned_to(WorkLog) # => [work_log1, work_log3]
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Template Class Methods
|
|
209
|
-
|
|
210
|
-
- `RailsTemplatable::Template.for_model(klass)` - Returns all templates ever used on the given model class
|
|
211
|
-
```ruby
|
|
212
|
-
RailsTemplatable::Template.for_model(Post) # => [template1, template2]
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Model Methods (with HasTemplates concern)
|
|
216
|
-
|
|
217
|
-
- `model.templates` - Returns all templates assigned to this record
|
|
218
|
-
- `model.templates << template` - Assign a template to this record
|
|
219
|
-
- `model.templates.delete(template)` - Remove a specific template
|
|
220
|
-
- `model.templates.clear` - Remove all templates
|
|
221
|
-
- `model.rails_templatable_assignments` - Direct access to join records
|
|
222
|
-
- `model.templates.where(category: "email_template")` - Filter by category
|
|
223
|
-
- `model.templates.html` - Get HTML format templates only
|
|
224
|
-
- `model.templates.markdown` - Get Markdown format templates only
|
|
225
|
-
- `model.templates.txt` - Get plain text templates only
|
|
226
|
-
|
|
227
|
-
## Advanced Usage
|
|
256
|
+
### Model Methods (with HasTemplate concern)
|
|
228
257
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```ruby
|
|
234
|
-
# Add custom fields to templates
|
|
235
|
-
add_column :rails_templatable_templates, :name, :string
|
|
236
|
-
add_column :rails_templatable_templates, :description, :text
|
|
237
|
-
add_column :rails_templatable_templates, :locale, :string, default: 'en'
|
|
238
|
-
|
|
239
|
-
# Add custom fields to assignments
|
|
240
|
-
add_column :rails_templatable_assignments, :priority, :integer, default: 0
|
|
241
|
-
add_column :rails_templatable_assignments, :active, :boolean, default: true
|
|
242
|
-
add_column :rails_templatable_assignments, :assigned_at, :datetime
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Accessing Assignment Data
|
|
246
|
-
|
|
247
|
-
```ruby
|
|
248
|
-
# Get assignment metadata
|
|
249
|
-
assignment = post.rails_templatable_assignments.find_by(template_id: 1)
|
|
250
|
-
assignment.priority # => 1
|
|
251
|
-
assignment.created_at # => assignment time
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Conditional Scopes
|
|
255
|
-
|
|
256
|
-
Add scopes to your models:
|
|
257
|
-
|
|
258
|
-
```ruby
|
|
259
|
-
class Post < ApplicationRecord
|
|
260
|
-
include RailsTemplatable::HasTemplates
|
|
261
|
-
|
|
262
|
-
scope :with_email_template, -> {
|
|
263
|
-
joins(:templates)
|
|
264
|
-
.where(rails_templatable_templates: { category: 'email_template' })
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
scope :with_html_templates, -> {
|
|
268
|
-
joins(:templates)
|
|
269
|
-
.where(rails_templatable_templates: { content_format: 0 })
|
|
270
|
-
}
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
# Usage
|
|
274
|
-
Post.with_email_template # All posts with email templates
|
|
275
|
-
Post.with_html_templates # All posts with HTML templates
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Checking Template Existence
|
|
279
|
-
|
|
280
|
-
```ruby
|
|
281
|
-
# Check if a post has templates from a specific category
|
|
282
|
-
post.templates.where(category: "email_template").exists? # => true/false
|
|
283
|
-
|
|
284
|
-
# Check if a post has HTML templates
|
|
285
|
-
post.templates.html.any? # => true/false
|
|
286
|
-
|
|
287
|
-
# Count templates by format
|
|
288
|
-
post.templates.html.count # => 2
|
|
289
|
-
post.templates.markdown.count # => 1
|
|
290
|
-
post.templates.txt.count # => 0
|
|
291
|
-
```
|
|
258
|
+
- `model.template` - Returns the assigned template or nil
|
|
259
|
+
- `model.template=(template)` - Assign a template (replaces existing)
|
|
260
|
+
- `model.update(template: template)` - Update template
|
|
261
|
+
- `model.update(template: nil)` - Remove template association
|
|
292
262
|
|
|
293
263
|
## Testing
|
|
294
264
|
|
|
@@ -301,27 +271,23 @@ ruby test_templatable.rb
|
|
|
301
271
|
|
|
302
272
|
Expected output:
|
|
303
273
|
```
|
|
304
|
-
🚀 Testing Rails Templatable Engine
|
|
305
|
-
|
|
274
|
+
🚀 Testing Rails Templatable Engine (1:N Relationship)
|
|
275
|
+
============================================================
|
|
306
276
|
|
|
307
277
|
📝 Creating templates...
|
|
308
|
-
✓ Created
|
|
309
|
-
✓ Created
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
📄 Creating Posts and WorkLogs...
|
|
313
|
-
✓ Created 2 Posts and 2 WorkLogs
|
|
314
|
-
|
|
315
|
-
🔗 Associating templates with models...
|
|
316
|
-
✓ Templates associated successfully
|
|
317
|
-
|
|
318
|
-
🔍 Testing queries...
|
|
319
|
-
Post1 has 2 templates
|
|
320
|
-
Post1 templates: email_template, documentation
|
|
321
|
-
...
|
|
278
|
+
✓ Created feature_request template
|
|
279
|
+
✓ Created bug_report template
|
|
280
|
+
...
|
|
322
281
|
|
|
323
282
|
✅ All tests passed successfully!
|
|
324
|
-
|
|
283
|
+
============================================================
|
|
284
|
+
|
|
285
|
+
📊 Summary:
|
|
286
|
+
- Created 5 templates
|
|
287
|
+
- Created 6 posts
|
|
288
|
+
- Created 3 work logs
|
|
289
|
+
- 1:N relationship verified: one record → one template
|
|
290
|
+
- 1:N relationship verified: one template → many records
|
|
325
291
|
```
|
|
326
292
|
|
|
327
293
|
## Project Structure
|
|
@@ -335,75 +301,78 @@ lib/
|
|
|
335
301
|
app/models/
|
|
336
302
|
├── rails_templatable/
|
|
337
303
|
│ ├── application_record.rb # Base AR class
|
|
338
|
-
│
|
|
339
|
-
│ └── template_assignment.rb # Join model
|
|
304
|
+
│ └── template.rb # Template model
|
|
340
305
|
└── models/concerns/
|
|
341
306
|
└── rails_templatable/
|
|
342
|
-
└──
|
|
307
|
+
└── has_template.rb # Concern for host models
|
|
343
308
|
db/migrate/
|
|
344
309
|
└── 20250207000000_create_rails_templatable_tables.rb # Migration
|
|
345
310
|
test/dummy/
|
|
346
311
|
├── app/models/
|
|
347
|
-
│ ├── post.rb # Example: Post with
|
|
348
|
-
│ └── work_log.rb # Example: WorkLog with
|
|
349
|
-
├── db/
|
|
312
|
+
│ ├── post.rb # Example: Post with HasTemplate
|
|
313
|
+
│ └── work_log.rb # Example: WorkLog with HasTemplate
|
|
314
|
+
├── db/migrate/
|
|
315
|
+
│ ├── xxx_add_template_to_posts.rb # Add template_id to posts
|
|
316
|
+
│ └── xxx_add_template_to_work_logs.rb # Add template_id to work_logs
|
|
350
317
|
└── test_templatable.rb # Integration test script
|
|
351
318
|
docs/
|
|
352
|
-
├── 01-
|
|
353
|
-
├── 02-usage.md
|
|
354
|
-
└── 03-
|
|
319
|
+
├── 01-design.md # Design document
|
|
320
|
+
├── 02-usage.md # Usage guide
|
|
321
|
+
└── 03-redesign-summary.md # Architecture redesign summary
|
|
355
322
|
```
|
|
356
323
|
|
|
324
|
+
## Architecture Decisions
|
|
325
|
+
|
|
326
|
+
### Why 1:N instead of N:N?
|
|
327
|
+
|
|
328
|
+
The original design used N:N (many-to-many) with a join table, but this was changed to 1:N (one-to-many) because:
|
|
329
|
+
- In practice, a document/post typically needs only one template
|
|
330
|
+
- Simpler database schema (no join table)
|
|
331
|
+
- More efficient queries (direct foreign key)
|
|
332
|
+
- Clearer semantics: "This post uses which template?"
|
|
333
|
+
|
|
334
|
+
### Why `category` instead of `type`?
|
|
335
|
+
|
|
336
|
+
Rails reserves the `type` column for Single Table Inheritance (STI). To avoid conflicts:
|
|
337
|
+
- We use `category` for template classification
|
|
338
|
+
- Users can define any category string
|
|
339
|
+
- No hardcoded enum or predefined types
|
|
340
|
+
|
|
341
|
+
### Why explicit table names?
|
|
342
|
+
|
|
343
|
+
To prevent any naming conflicts:
|
|
344
|
+
- `rails_templatable_templates` - Template storage
|
|
345
|
+
- No reliance on Rails auto-inflection
|
|
346
|
+
- Clear namespace isolation
|
|
347
|
+
|
|
357
348
|
## Comparison with rails_badgeable
|
|
358
349
|
|
|
359
350
|
| Feature | rails_badgeable | rails_templatable |
|
|
360
351
|
|---------|-----------------|-------------------|
|
|
361
352
|
| Main Model | Badge | Template |
|
|
353
|
+
| Relationship | N:N (many-to-many) | 1:N (one-to-many) |
|
|
354
|
+
| Join Table | badge_assignments | None (direct foreign key) |
|
|
355
|
+
| Model Association | has_many :badges | belongs_to :template |
|
|
362
356
|
| Fields | name, description | category, content, content_format |
|
|
363
|
-
| Enum Support | No | Yes (content_format
|
|
364
|
-
| Polymorphic Name | assignable |
|
|
365
|
-
| Concern | HasBadges |
|
|
366
|
-
| STI Conflict Handling | N/A | Uses `category` to avoid `type` conflict |
|
|
357
|
+
| Enum Support | No | Yes (content_format) |
|
|
358
|
+
| Polymorphic Name | assignable | N/A (not polymorphic) |
|
|
359
|
+
| Concern | HasBadges | HasTemplate |
|
|
367
360
|
|
|
368
361
|
## Usage Notes for Agents
|
|
369
362
|
|
|
370
|
-
- **Always use full namespace:** `RailsTemplatable::Template` (no alias generator
|
|
363
|
+
- **Always use full namespace:** `RailsTemplatable::Template` (no alias generator)
|
|
371
364
|
- **Categories are user-defined:** No predefined categories, use any string value
|
|
372
365
|
- **Content formats are enforced:** Use symbols: `:html`, `:markdown`, `:txt`
|
|
373
|
-
- **
|
|
374
|
-
- **
|
|
366
|
+
- **One record = One template:** Assigning a new template replaces the old one
|
|
367
|
+
- **Direct foreign key:** Each model needs its own `template_id` column
|
|
368
|
+
- **No join table:** Simpler schema than rails_badgeable
|
|
375
369
|
- **Engine is not mountable:** No routes, controllers, or views included
|
|
376
370
|
- **Migrations must be copied:** Use `rails railties:install:migrations FROM=rails_templatable`
|
|
377
371
|
- **Custom fields require migration:** Add columns directly to tables if needed
|
|
378
|
-
- **Join table accessible:** `model.rails_templatable_assignments` for metadata access
|
|
379
372
|
- **`category` field is indexed:** Efficient queries by category
|
|
380
373
|
- **Default content_format is TXT:** New templates default to plain text (2)
|
|
381
374
|
- **Rails 8.x enum syntax:** Must use `enum :content_format, { ... }` not `enum content_format: { ... }`
|
|
382
375
|
|
|
383
|
-
## Architecture Decisions
|
|
384
|
-
|
|
385
|
-
### Why `category` instead of `type`?
|
|
386
|
-
|
|
387
|
-
Rails reserves the `type` column for Single Table Inheritance (STI). To avoid conflicts:
|
|
388
|
-
- We use `category` for template classification
|
|
389
|
-
- Users can define any category string (email_template, documentation, etc.)
|
|
390
|
-
- No hardcoded enum or predefined types
|
|
391
|
-
|
|
392
|
-
### Why explicit table names?
|
|
393
|
-
|
|
394
|
-
To prevent any naming conflicts:
|
|
395
|
-
- `rails_templatable_templates` - Template storage
|
|
396
|
-
- `rails_templatable_assignments` - Polymorphic join table
|
|
397
|
-
- No reliance on Rails auto-inflection
|
|
398
|
-
|
|
399
|
-
### Why enum for content_format?
|
|
400
|
-
|
|
401
|
-
Using Rails enum provides:
|
|
402
|
-
- Type safety (only valid formats)
|
|
403
|
-
- Helper methods (`html`, `markdown`, `txt`)
|
|
404
|
-
- Integer storage for efficiency
|
|
405
|
-
- Easy to extend with new formats
|
|
406
|
-
|
|
407
376
|
## Development
|
|
408
377
|
|
|
409
378
|
- Rails Engine (non-mountable)
|
|
@@ -411,17 +380,16 @@ Using Rails enum provides:
|
|
|
411
380
|
- Rails 6.0+ compatible (tested on Rails 8.1.2)
|
|
412
381
|
- MIT License
|
|
413
382
|
- Author: aric.zheng <1290657123@qq.com>
|
|
414
|
-
- Version: 0.1.
|
|
383
|
+
- Version: 0.1.1
|
|
415
384
|
|
|
416
385
|
## Future Enhancements
|
|
417
386
|
|
|
418
387
|
Planned features for future versions:
|
|
419
388
|
- Template variable interpolation (replace `{{name}}` with actual data)
|
|
420
389
|
- Template versioning system
|
|
421
|
-
- Template inheritance and overriding
|
|
422
390
|
- Template preview functionality
|
|
423
391
|
- I18n multi-language support
|
|
424
|
-
-
|
|
392
|
+
- Template validation based on structure
|
|
425
393
|
|
|
426
394
|
## Contributing
|
|
427
395
|
|
|
@@ -431,3 +399,4 @@ When contributing to rails_templatable:
|
|
|
431
399
|
3. Add tests for new features
|
|
432
400
|
4. Update this llms.txt file with API changes
|
|
433
401
|
5. Ensure Rails 6.0+ compatibility
|
|
402
|
+
6. Remember: 1:N relationship, not N:N
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_templatable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- aric.zheng
|
|
@@ -31,7 +31,9 @@ dependencies:
|
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '9.0'
|
|
33
33
|
description: A lightweight Rails Engine that enables any ActiveRecord model to use
|
|
34
|
-
templates
|
|
34
|
+
predefined templates via a simple one-to-many relationship. Each record has one
|
|
35
|
+
template, templates can be reused across multiple records. Supports HTML, Markdown,
|
|
36
|
+
and plain text formats with flexible categories.
|
|
35
37
|
email:
|
|
36
38
|
- 1290657123@qq.com
|
|
37
39
|
executables: []
|
|
@@ -41,16 +43,9 @@ files:
|
|
|
41
43
|
- MIT-LICENSE
|
|
42
44
|
- README.md
|
|
43
45
|
- Rakefile
|
|
44
|
-
- app/
|
|
45
|
-
- app/controllers/rails_templatable/application_controller.rb
|
|
46
|
-
- app/helpers/rails_templatable/application_helper.rb
|
|
47
|
-
- app/jobs/rails_templatable/application_job.rb
|
|
48
|
-
- app/mailers/rails_templatable/application_mailer.rb
|
|
49
|
-
- app/models/concerns/rails_templatable/has_templates.rb
|
|
46
|
+
- app/models/concerns/rails_templatable/has_template.rb
|
|
50
47
|
- app/models/rails_templatable/application_record.rb
|
|
51
48
|
- app/models/rails_templatable/template.rb
|
|
52
|
-
- app/models/rails_templatable/template_assignment.rb
|
|
53
|
-
- app/views/layouts/rails_templatable/application.html.erb
|
|
54
49
|
- config/routes.rb
|
|
55
50
|
- db/migrate/20250207000000_create_rails_templatable_tables.rb
|
|
56
51
|
- lib/rails_templatable.rb
|
|
@@ -84,5 +79,5 @@ requirements: []
|
|
|
84
79
|
rubygems_version: 3.5.22
|
|
85
80
|
signing_key:
|
|
86
81
|
specification_version: 4
|
|
87
|
-
summary: A Rails engine for
|
|
82
|
+
summary: A Rails engine for template management with 1:N relationship.
|
|
88
83
|
test_files: []
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
-
* listed below.
|
|
4
|
-
*
|
|
5
|
-
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
-
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
-
*
|
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
-
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
-
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
-
* It is generally better to create a new file per style scope.
|
|
12
|
-
*
|
|
13
|
-
*= require_tree .
|
|
14
|
-
*= require_self
|
|
15
|
-
*/
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module RailsTemplatable
|
|
2
|
-
module HasTemplates
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
included do
|
|
6
|
-
has_many :rails_templatable_assignments,
|
|
7
|
-
as: :templatable,
|
|
8
|
-
class_name: "RailsTemplatable::TemplateAssignment",
|
|
9
|
-
dependent: :destroy
|
|
10
|
-
|
|
11
|
-
has_many :templates,
|
|
12
|
-
through: :rails_templatable_assignments,
|
|
13
|
-
class_name: "RailsTemplatable::Template"
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module RailsTemplatable
|
|
2
|
-
class TemplateAssignment < ApplicationRecord
|
|
3
|
-
self.table_name = "rails_templatable_assignments"
|
|
4
|
-
|
|
5
|
-
belongs_to :template, class_name: "RailsTemplatable::Template"
|
|
6
|
-
belongs_to :templatable, polymorphic: true
|
|
7
|
-
|
|
8
|
-
validates :template, presence: true
|
|
9
|
-
validates :templatable, presence: true
|
|
10
|
-
validates :template_id, uniqueness: { scope: [:templatable_type, :templatable_id] }
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Rails templatable</title>
|
|
5
|
-
<%= csrf_meta_tags %>
|
|
6
|
-
<%= csp_meta_tag %>
|
|
7
|
-
|
|
8
|
-
<%= yield :head %>
|
|
9
|
-
|
|
10
|
-
<%= stylesheet_link_tag "rails_templatable/application", media: "all" %>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
|
|
14
|
-
<%= yield %>
|
|
15
|
-
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|