blanks 1.0.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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +427 -0
  5. data/Rakefile +8 -0
  6. data/examples/advanced_features_example.rb +81 -0
  7. data/examples/assign_from_model_example.rb +54 -0
  8. data/examples/model_name_example.rb +31 -0
  9. data/examples/normalization_example.rb +39 -0
  10. data/examples/post_form_example.rb +52 -0
  11. data/lib/blanks/association_proxy.rb +92 -0
  12. data/lib/blanks/associations.rb +58 -0
  13. data/lib/blanks/base.rb +256 -0
  14. data/lib/blanks/model_naming.rb +24 -0
  15. data/lib/blanks/nested_attributes.rb +131 -0
  16. data/lib/blanks/normalization.rb +38 -0
  17. data/lib/blanks/version.rb +3 -0
  18. data/lib/blanks.rb +18 -0
  19. data/spec/blanks/association_proxy_spec.rb +214 -0
  20. data/spec/blanks/associations_spec.rb +185 -0
  21. data/spec/blanks/attributes_extraction_spec.rb +138 -0
  22. data/spec/blanks/base_spec.rb +361 -0
  23. data/spec/blanks/callbacks_spec.rb +60 -0
  24. data/spec/blanks/custom_primary_key_spec.rb +168 -0
  25. data/spec/blanks/dirty_tracking_spec.rb +61 -0
  26. data/spec/blanks/i18n_spec.rb +33 -0
  27. data/spec/blanks/id_tracking_spec.rb +168 -0
  28. data/spec/blanks/inherit_attributes_from_spec.rb +148 -0
  29. data/spec/blanks/inherit_validations_from_spec.rb +260 -0
  30. data/spec/blanks/model_naming_spec.rb +82 -0
  31. data/spec/blanks/nested_attributes_spec.rb +378 -0
  32. data/spec/blanks/normalization_spec.rb +122 -0
  33. data/spec/dummy/Gemfile +10 -0
  34. data/spec/dummy/Gemfile.lock +242 -0
  35. data/spec/dummy/Rakefile +5 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  37. data/spec/dummy/app/controllers/simple_form/articles_controller.rb +65 -0
  38. data/spec/dummy/app/controllers/simple_form/posts_controller.rb +59 -0
  39. data/spec/dummy/app/controllers/standard/articles_controller.rb +65 -0
  40. data/spec/dummy/app/controllers/standard/posts_controller.rb +59 -0
  41. data/spec/dummy/app/forms/article_form.rb +17 -0
  42. data/spec/dummy/app/forms/cover_image_form.rb +9 -0
  43. data/spec/dummy/app/forms/post_form.rb +10 -0
  44. data/spec/dummy/app/forms/tag_form.rb +12 -0
  45. data/spec/dummy/app/models/application_record.rb +5 -0
  46. data/spec/dummy/app/models/article.rb +11 -0
  47. data/spec/dummy/app/models/cover_image.rb +7 -0
  48. data/spec/dummy/app/models/post.rb +8 -0
  49. data/spec/dummy/app/models/tag.rb +7 -0
  50. data/spec/dummy/app/views/layouts/application.html.erb +43 -0
  51. data/spec/dummy/app/views/simple_form/articles/_form.html.erb +43 -0
  52. data/spec/dummy/app/views/simple_form/articles/edit.html.erb +5 -0
  53. data/spec/dummy/app/views/simple_form/articles/index.html.erb +29 -0
  54. data/spec/dummy/app/views/simple_form/articles/new.html.erb +5 -0
  55. data/spec/dummy/app/views/simple_form/articles/show.html.erb +29 -0
  56. data/spec/dummy/app/views/simple_form/posts/_form.html.erb +19 -0
  57. data/spec/dummy/app/views/simple_form/posts/edit.html.erb +5 -0
  58. data/spec/dummy/app/views/simple_form/posts/index.html.erb +27 -0
  59. data/spec/dummy/app/views/simple_form/posts/new.html.erb +5 -0
  60. data/spec/dummy/app/views/simple_form/posts/show.html.erb +12 -0
  61. data/spec/dummy/app/views/standard/articles/_form.html.erb +61 -0
  62. data/spec/dummy/app/views/standard/articles/edit.html.erb +5 -0
  63. data/spec/dummy/app/views/standard/articles/index.html.erb +29 -0
  64. data/spec/dummy/app/views/standard/articles/new.html.erb +5 -0
  65. data/spec/dummy/app/views/standard/articles/show.html.erb +29 -0
  66. data/spec/dummy/app/views/standard/posts/_form.html.erb +30 -0
  67. data/spec/dummy/app/views/standard/posts/edit.html.erb +5 -0
  68. data/spec/dummy/app/views/standard/posts/index.html.erb +27 -0
  69. data/spec/dummy/app/views/standard/posts/new.html.erb +5 -0
  70. data/spec/dummy/app/views/standard/posts/show.html.erb +12 -0
  71. data/spec/dummy/bin/rails +6 -0
  72. data/spec/dummy/config/application.rb +18 -0
  73. data/spec/dummy/config/boot.rb +5 -0
  74. data/spec/dummy/config/database.yml +12 -0
  75. data/spec/dummy/config/environment.rb +5 -0
  76. data/spec/dummy/config/environments/development.rb +9 -0
  77. data/spec/dummy/config/environments/test.rb +8 -0
  78. data/spec/dummy/config/initializers/simple_form.rb +21 -0
  79. data/spec/dummy/config/routes.rb +15 -0
  80. data/spec/dummy/config/storage.yml +3 -0
  81. data/spec/dummy/config.ru +5 -0
  82. data/spec/dummy/db/migrate/1_create_posts.rb +12 -0
  83. data/spec/dummy/db/migrate/2_create_articles.rb +12 -0
  84. data/spec/dummy/db/migrate/3_create_cover_images.rb +12 -0
  85. data/spec/dummy/db/migrate/4_create_tags.rb +12 -0
  86. data/spec/dummy/db/migrate/5_create_active_storage_tables.rb +36 -0
  87. data/spec/dummy/db/schema.rb +82 -0
  88. data/spec/dummy/spec/examples.txt +145 -0
  89. data/spec/dummy/tmp/local_secret.txt +1 -0
  90. data/spec/examples.txt +157 -0
  91. data/spec/spec_helper.rb +21 -0
  92. metadata +159 -0
@@ -0,0 +1,29 @@
1
+ <h1>Articles (SimpleForm)</h1>
2
+
3
+ <p><%= link_to "New Article", new_simple_form_article_path %></p>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Title</th>
9
+ <th>Author</th>
10
+ <th>Cover Image</th>
11
+ <th>Tags</th>
12
+ <th>Actions</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @articles.each do |article| %>
17
+ <tr>
18
+ <td><%= link_to article.title, simple_form_article_path(article) %></td>
19
+ <td><%= article.author_name %></td>
20
+ <td><%= article.cover_image&.url.present? ? "Yes" : "No" %></td>
21
+ <td><%= article.tags.map(&:name).join(", ") %></td>
22
+ <td>
23
+ <%= link_to "Edit", edit_simple_form_article_path(article) %> |
24
+ <%= link_to "Delete", simple_form_article_path(article), method: :delete, data: { confirm: "Are you sure?" } %>
25
+ </td>
26
+ </tr>
27
+ <% end %>
28
+ </tbody>
29
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New Article (SimpleForm with nested)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", simple_form_articles_path %></p>
@@ -0,0 +1,29 @@
1
+ <h1><%= @article.title %></h1>
2
+
3
+ <p><strong>Author:</strong> <%= @article.author_name %></p>
4
+
5
+ <% if @article.cover_image %>
6
+ <div class="nested">
7
+ <h4>Cover Image</h4>
8
+ <p><strong>URL:</strong> <%= @article.cover_image.url %></p>
9
+ <p><strong>Alt text:</strong> <%= @article.cover_image.alt_text %></p>
10
+ </div>
11
+ <% end %>
12
+
13
+ <div>
14
+ <%= simple_format(@article.body) %>
15
+ </div>
16
+
17
+ <% if @article.tags.any? %>
18
+ <h3>Tags</h3>
19
+ <ul>
20
+ <% @article.tags.each do |tag| %>
21
+ <li><%= tag.name %> <% if tag.color.present? %>(<%= tag.color %>)<% end %></li>
22
+ <% end %>
23
+ </ul>
24
+ <% end %>
25
+
26
+ <p>
27
+ <%= link_to "Edit", edit_simple_form_article_path(@article) %> |
28
+ <%= link_to "Back", simple_form_articles_path %>
29
+ </p>
@@ -0,0 +1,19 @@
1
+ <%= simple_form_for form, url: form.persisted? ? simple_form_post_path(form) : simple_form_posts_path do |f| %>
2
+ <% if form.errors.any? %>
3
+ <div class="error">
4
+ <ul>
5
+ <% form.errors.full_messages.each do |msg| %>
6
+ <li><%= msg %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
11
+
12
+ <%= f.input :title %>
13
+ <%= f.input :content, as: :text %>
14
+ <%= f.input :published, as: :boolean %>
15
+
16
+ <div class="actions">
17
+ <%= f.button :submit, class: "btn" %>
18
+ </div>
19
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <h1>Edit Post (SimpleForm)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", simple_form_posts_path %></p>
@@ -0,0 +1,27 @@
1
+ <h1>Posts (SimpleForm)</h1>
2
+
3
+ <p><%= link_to "New Post", new_simple_form_post_path %></p>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Title</th>
9
+ <th>Published</th>
10
+ <th>Created</th>
11
+ <th>Actions</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% @posts.each do |post| %>
16
+ <tr>
17
+ <td><%= link_to post.title, simple_form_post_path(post) %></td>
18
+ <td><%= post.published? ? "Yes" : "No" %></td>
19
+ <td><%= post.created_at.strftime("%Y-%m-%d") %></td>
20
+ <td>
21
+ <%= link_to "Edit", edit_simple_form_post_path(post) %> |
22
+ <%= link_to "Delete", simple_form_post_path(post), method: :delete, data: { confirm: "Are you sure?" } %>
23
+ </td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New Post (SimpleForm)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", simple_form_posts_path %></p>
@@ -0,0 +1,12 @@
1
+ <h1><%= @post.title %></h1>
2
+
3
+ <p><strong>Published:</strong> <%= @post.published? ? "Yes" : "No" %></p>
4
+
5
+ <div>
6
+ <%= simple_format(@post.content) %>
7
+ </div>
8
+
9
+ <p>
10
+ <%= link_to "Edit", edit_simple_form_post_path(@post) %> |
11
+ <%= link_to "Back", simple_form_posts_path %>
12
+ </p>
@@ -0,0 +1,61 @@
1
+ <%= form_with model: form, url: form.persisted? ? standard_article_path(form) : standard_articles_path do |f| %>
2
+ <% if form.errors.any? %>
3
+ <div class="error">
4
+ <ul>
5
+ <% form.errors.full_messages.each do |msg| %>
6
+ <li><%= msg %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
11
+
12
+ <div class="field">
13
+ <%= f.label :title %>
14
+ <%= f.text_field :title %>
15
+ </div>
16
+
17
+ <div class="field">
18
+ <%= f.label :body %>
19
+ <%= f.text_area :body, rows: 6 %>
20
+ </div>
21
+
22
+ <div class="field">
23
+ <%= f.label :author_name %>
24
+ <%= f.text_field :author_name %>
25
+ </div>
26
+
27
+ <div class="nested">
28
+ <h4>Cover Image</h4>
29
+ <%= f.fields_for :cover_image do |ci| %>
30
+ <div class="field">
31
+ <%= ci.label :url %>
32
+ <%= ci.text_field :url, placeholder: "https://example.com/image.jpg" %>
33
+ </div>
34
+ <div class="field">
35
+ <%= ci.label :alt_text %>
36
+ <%= ci.text_field :alt_text %>
37
+ </div>
38
+ <% end %>
39
+ </div>
40
+
41
+ <div class="nested">
42
+ <h4>Tags</h4>
43
+ <%= f.fields_for :tags do |tag| %>
44
+ <div style="display: flex; gap: 10px; margin-bottom: 10px; align-items: center;">
45
+ <% if tag.object.persisted? %>
46
+ <%= tag.hidden_field :id %>
47
+ <% end %>
48
+ <%= tag.text_field :name, placeholder: "Tag name" %>
49
+ <%= tag.text_field :color, placeholder: "#ff0000" %>
50
+ <% if tag.object.persisted? %>
51
+ <%= tag.label :_destroy, "Delete" %>
52
+ <%= tag.check_box :_destroy %>
53
+ <% end %>
54
+ </div>
55
+ <% end %>
56
+ </div>
57
+
58
+ <div class="actions">
59
+ <%= f.submit class: "btn" %>
60
+ </div>
61
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <h1>Edit Article (Rails Form Helpers with nested)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", standard_articles_path %></p>
@@ -0,0 +1,29 @@
1
+ <h1>Articles (Rails Form Helpers)</h1>
2
+
3
+ <p><%= link_to "New Article", new_standard_article_path %></p>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Title</th>
9
+ <th>Author</th>
10
+ <th>Cover Image</th>
11
+ <th>Tags</th>
12
+ <th>Actions</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @articles.each do |article| %>
17
+ <tr>
18
+ <td><%= link_to article.title, standard_article_path(article) %></td>
19
+ <td><%= article.author_name %></td>
20
+ <td><%= article.cover_image&.url.present? ? "Yes" : "No" %></td>
21
+ <td><%= article.tags.map(&:name).join(", ") %></td>
22
+ <td>
23
+ <%= link_to "Edit", edit_standard_article_path(article) %> |
24
+ <%= link_to "Delete", standard_article_path(article), method: :delete, data: { confirm: "Are you sure?" } %>
25
+ </td>
26
+ </tr>
27
+ <% end %>
28
+ </tbody>
29
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New Article (Rails Form Helpers with nested)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", standard_articles_path %></p>
@@ -0,0 +1,29 @@
1
+ <h1><%= @article.title %></h1>
2
+
3
+ <p><strong>Author:</strong> <%= @article.author_name %></p>
4
+
5
+ <% if @article.cover_image %>
6
+ <div class="nested">
7
+ <h4>Cover Image</h4>
8
+ <p><strong>URL:</strong> <%= @article.cover_image.url %></p>
9
+ <p><strong>Alt text:</strong> <%= @article.cover_image.alt_text %></p>
10
+ </div>
11
+ <% end %>
12
+
13
+ <div>
14
+ <%= simple_format(@article.body) %>
15
+ </div>
16
+
17
+ <% if @article.tags.any? %>
18
+ <h3>Tags</h3>
19
+ <ul>
20
+ <% @article.tags.each do |tag| %>
21
+ <li><%= tag.name %> <% if tag.color.present? %>(<%= tag.color %>)<% end %></li>
22
+ <% end %>
23
+ </ul>
24
+ <% end %>
25
+
26
+ <p>
27
+ <%= link_to "Edit", edit_standard_article_path(@article) %> |
28
+ <%= link_to "Back", standard_articles_path %>
29
+ </p>
@@ -0,0 +1,30 @@
1
+ <%= form_with model: form, url: form.persisted? ? standard_post_path(form) : standard_posts_path do |f| %>
2
+ <% if form.errors.any? %>
3
+ <div class="error">
4
+ <ul>
5
+ <% form.errors.full_messages.each do |msg| %>
6
+ <li><%= msg %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
11
+
12
+ <div class="field">
13
+ <%= f.label :title %>
14
+ <%= f.text_field :title %>
15
+ </div>
16
+
17
+ <div class="field">
18
+ <%= f.label :content %>
19
+ <%= f.text_area :content, rows: 6 %>
20
+ </div>
21
+
22
+ <div class="field">
23
+ <%= f.label :published %>
24
+ <%= f.check_box :published %>
25
+ </div>
26
+
27
+ <div class="actions">
28
+ <%= f.submit class: "btn" %>
29
+ </div>
30
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <h1>Edit Post (Rails Form Helpers)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", standard_posts_path %></p>
@@ -0,0 +1,27 @@
1
+ <h1>Posts (Rails Form Helpers)</h1>
2
+
3
+ <p><%= link_to "New Post", new_standard_post_path %></p>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Title</th>
9
+ <th>Published</th>
10
+ <th>Created</th>
11
+ <th>Actions</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% @posts.each do |post| %>
16
+ <tr>
17
+ <td><%= link_to post.title, standard_post_path(post) %></td>
18
+ <td><%= post.published? ? "Yes" : "No" %></td>
19
+ <td><%= post.created_at.strftime("%Y-%m-%d") %></td>
20
+ <td>
21
+ <%= link_to "Edit", edit_standard_post_path(post) %> |
22
+ <%= link_to "Delete", standard_post_path(post), method: :delete, data: { confirm: "Are you sure?" } %>
23
+ </td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New Post (Rails Form Helpers)</h1>
2
+
3
+ <%= render "form", form: @form %>
4
+
5
+ <p><%= link_to "Back", standard_posts_path %></p>
@@ -0,0 +1,12 @@
1
+ <h1><%= @post.title %></h1>
2
+
3
+ <p><strong>Published:</strong> <%= @post.published? ? "Yes" : "No" %></p>
4
+
5
+ <div>
6
+ <%= simple_format(@post.content) %>
7
+ </div>
8
+
9
+ <p>
10
+ <%= link_to "Edit", edit_standard_post_path(@post) %> |
11
+ <%= link_to "Back", standard_posts_path %>
12
+ </p>
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ APP_PATH = File.expand_path("../config/application", __dir__)
5
+ require_relative "../config/boot"
6
+ require "rails/commands"
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "boot"
4
+
5
+ require "rails/all"
6
+
7
+ Bundler.require(*Rails.groups)
8
+
9
+ require "blanks"
10
+
11
+ module Dummy
12
+ class Application < Rails::Application
13
+ config.load_defaults Rails::VERSION::STRING.to_f
14
+ config.eager_load = false
15
+ config.active_storage.service = :local
16
+ config.autoload_paths << Rails.root.join("app/forms")
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
4
+
5
+ require "bundler/setup"
@@ -0,0 +1,12 @@
1
+ default: &default
2
+ adapter: sqlite3
3
+ pool: 5
4
+ timeout: 5000
5
+
6
+ development:
7
+ <<: *default
8
+ database: db/development.sqlite3
9
+
10
+ test:
11
+ <<: *default
12
+ database: db/test.sqlite3
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "application"
4
+
5
+ Rails.application.initialize!
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.configure do
4
+ config.cache_classes = false
5
+ config.eager_load = false
6
+ config.consider_all_requests_local = true
7
+ config.active_storage.service = :local
8
+ config.secret_key_base = "dev_secret_key_base_for_dummy_app_only"
9
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.configure do
4
+ config.cache_classes = true
5
+ config.eager_load = false
6
+ config.consider_all_requests_local = true
7
+ config.active_storage.service = :local
8
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ SimpleForm.setup do |config|
4
+ config.button_class = "btn"
5
+ config.default_wrapper = :default
6
+ config.boolean_style = :inline
7
+
8
+ config.wrappers :default, class: :input, hint_class: :hint, error_class: :error do |b|
9
+ b.use :html5
10
+ b.use :placeholder
11
+ b.optional :maxlength
12
+ b.optional :minlength
13
+ b.optional :pattern
14
+ b.optional :min_max
15
+ b.optional :readonly
16
+ b.use :label
17
+ b.use :input
18
+ b.use :error, wrap_with: { tag: :span, class: :error }
19
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.routes.draw do
4
+ namespace :simple_form do
5
+ resources :posts
6
+ resources :articles
7
+ end
8
+
9
+ namespace :standard do
10
+ resources :posts
11
+ resources :articles
12
+ end
13
+
14
+ root to: "simple_form/posts#index"
15
+ end
@@ -0,0 +1,3 @@
1
+ local:
2
+ service: Disk
3
+ root: <%= Rails.root.join("storage") %>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "config/environment"
4
+
5
+ run Rails.application
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreatePosts < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :posts do |t|
6
+ t.string :title, null: false
7
+ t.text :content
8
+ t.boolean :published, default: false
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateArticles < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :articles do |t|
6
+ t.string :title, null: false
7
+ t.text :body
8
+ t.string :author_name
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateCoverImages < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :cover_images do |t|
6
+ t.references :article, null: false, foreign_key: true
7
+ t.string :url, null: false
8
+ t.string :alt_text
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateTags < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :tags do |t|
6
+ t.references :article, null: false, foreign_key: true
7
+ t.string :name, null: false
8
+ t.string :color
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActiveStorageTables < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :active_storage_blobs do |t|
6
+ t.string :key, null: false
7
+ t.string :filename, null: false
8
+ t.string :content_type
9
+ t.text :metadata
10
+ t.string :service_name, null: false
11
+ t.bigint :byte_size, null: false
12
+ t.string :checksum
13
+
14
+ t.index [:key], unique: true
15
+ t.timestamps
16
+ end
17
+
18
+ create_table :active_storage_attachments do |t|
19
+ t.string :name, null: false
20
+ t.references :record, null: false, polymorphic: true, index: false
21
+ t.references :blob, null: false
22
+
23
+ t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true
24
+ t.foreign_key :active_storage_blobs, column: :blob_id
25
+ t.timestamps
26
+ end
27
+
28
+ create_table :active_storage_variant_records do |t|
29
+ t.belongs_to :blob, null: false, index: false
30
+ t.string :variation_digest, null: false
31
+
32
+ t.index [:blob_id, :variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true
33
+ t.foreign_key :active_storage_blobs, column: :blob_id
34
+ end
35
+ end
36
+ end