rest_framework 0.9.4 → 0.9.6

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +130 -0
  4. data/VERSION +1 -1
  5. data/app/views/layouts/rest_framework.html.erb +9 -183
  6. data/app/views/rest_framework/_breadcrumbs.html.erb +27 -0
  7. data/app/views/rest_framework/_head.html.erb +348 -190
  8. data/app/views/rest_framework/_header.html.erb +15 -0
  9. data/app/views/rest_framework/_heading.html.erb +10 -0
  10. data/app/views/rest_framework/_payloads.html.erb +36 -0
  11. data/app/views/rest_framework/_request_metadata.html.erb +16 -0
  12. data/app/views/rest_framework/_routes_and_forms.html.erb +52 -0
  13. data/app/views/rest_framework/head/_external.html.erb +7 -2
  14. data/app/views/rest_framework/header/_mode.html.erb +14 -0
  15. data/app/views/rest_framework/heading/_actions.html.erb +9 -0
  16. data/app/views/rest_framework/{_routes.html.erb → routes_and_forms/_routes.html.erb} +2 -2
  17. data/lib/rest_framework/controller_mixins/base.rb +11 -12
  18. data/lib/rest_framework/engine.rb +5 -3
  19. data/lib/rest_framework/filters/ransack.rb +6 -6
  20. data/lib/rest_framework/version.rb +0 -6
  21. data/lib/rest_framework.rb +25 -13
  22. data/vendor/assets/javascripts/rest_framework/external.min.js +1256 -0
  23. data/vendor/assets/stylesheets/rest_framework/{bootstrap-icons.css → external.min.css} +415 -1
  24. data/vendor/assets/stylesheets/rest_framework/{highlight-a11y-dark.css → highlight-a11y-dark.min.css} +1 -1
  25. data/vendor/assets/stylesheets/rest_framework/{highlight-a11y-light.css → highlight-a11y-light.min.css} +1 -1
  26. metadata +18 -35
  27. data/README.md +0 -1
  28. data/app/views/rest_framework/head/_shared.html +0 -164
  29. data/docs/CNAME +0 -1
  30. data/docs/Gemfile +0 -5
  31. data/docs/Gemfile.lock +0 -264
  32. data/docs/_config.yml +0 -19
  33. data/docs/_guide/1_routers.md +0 -110
  34. data/docs/_guide/2_controllers.md +0 -342
  35. data/docs/_guide/3_serializers.md +0 -60
  36. data/docs/_guide/4_filtering_and_ordering.md +0 -41
  37. data/docs/_guide/5_pagination.md +0 -21
  38. data/docs/_includes/anchor_headings.html +0 -144
  39. data/docs/_includes/external.html +0 -9
  40. data/docs/_includes/head.html +0 -155
  41. data/docs/_includes/header.html +0 -58
  42. data/docs/_includes/shared.html +0 -164
  43. data/docs/_layouts/default.html +0 -11
  44. data/docs/assets/images/favicon.ico +0 -0
  45. data/docs/index.md +0 -133
  46. data/vendor/assets/javascripts/rest_framework/bootstrap.js +0 -7
  47. data/vendor/assets/javascripts/rest_framework/highlight-json.js +0 -7
  48. data/vendor/assets/javascripts/rest_framework/highlight-xml.js +0 -29
  49. data/vendor/assets/javascripts/rest_framework/highlight.js +0 -1202
  50. data/vendor/assets/javascripts/rest_framework/neatjson.js +0 -8
  51. data/vendor/assets/javascripts/rest_framework/trix.js +0 -6
  52. data/vendor/assets/stylesheets/rest_framework/bootstrap.css +0 -6
  53. data/vendor/assets/stylesheets/rest_framework/trix.css +0 -410
  54. /data/app/views/rest_framework/{_html_form.html.erb → routes_and_forms/_html_form.html.erb} +0 -0
  55. /data/app/views/rest_framework/{_raw_form.html.erb → routes_and_forms/_raw_form.html.erb} +0 -0
  56. /data/app/views/rest_framework/{_route.html.erb → routes_and_forms/routes/_route.html.erb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64cf1d1a710b4ee12f57fb30cb23d3ba000a2e9072ff991cb40aaa20c3cdf81b
4
- data.tar.gz: 212edeefb3ffecaf05658cfa301cb161e09201e09fe7dd4deb490c152bebe211
3
+ metadata.gz: c26bdb290be334d911d6270e010568d3674f12a3e63dfa0f51337b242907317c
4
+ data.tar.gz: '07897cd01fe0f3df22af8d8466b49835d8e1db623b8e6066b407675989e0b9b2'
5
5
  SHA512:
6
- metadata.gz: 907aef47db6388a52f017d3f6a02f8ca07f4d67c59e68ff0a3004cff559ca7fcf4fe88937a1943b6a8afe81802df18d3b31249cc808dd512689bd5f0c62b2b01
7
- data.tar.gz: 871befe2e9b01875d57171188db84a6eca226d2d37cd170c6c3de9b05f8bd75466447276f22a16f64af030d0f5dfb786790ace1edd59fdc4375f7ede7545a175
6
+ metadata.gz: 71952c62c0f9165d837afbec82168ce11361c6e9655d4c73beabfe0e7de40f18c6cb059a7b76b5bf5fe38a5f6c3b545f8df7c5b60724900cf1d1d32a5b3cb8e8
7
+ data.tar.gz: 74ed89e118d69516d0bdd6a5cdcfa99e125fa80c45a48af2c99b8c79744041519c3e316a4f82c2737cdb41949a3bf9243c93b90090ab426880778d0b81fb1c61
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Gregory N. Schmit
3
+ Copyright (c) 2023 Gregory N. Schmit
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # Rails REST Framework
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rest_framework.svg)](https://badge.fury.io/rb/rest_framework)
4
+ [![Pipeline](https://github.com/gregschmit/rails-rest-framework/actions/workflows/pipeline.yml/badge.svg)](https://github.com/gregschmit/rails-rest-framework/actions/workflows/pipeline.yml)
5
+ [![Coverage](https://coveralls.io/repos/github/gregschmit/rails-rest-framework/badge.svg?branch=master)](https://coveralls.io/github/gregschmit/rails-rest-framework?branch=master)
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/ba5df7706cb544d78555/maintainability)](https://codeclimate.com/github/gregschmit/rails-rest-framework/maintainability)
7
+
8
+ A framework for DRY RESTful APIs in Ruby on Rails.
9
+
10
+ **The Problem**: Building controllers for APIs usually involves writing a lot of redundant CRUD
11
+ logic, and routing them can be obnoxious. Building and maintaining features like ordering,
12
+ filtering, and pagination can be tedious.
13
+
14
+ **The Solution**: This framework implements browsable API responses, CRUD actions for your models,
15
+ and features like ordering/filtering/pagination, so you can focus on building awesome APIs.
16
+
17
+ Website/Guide: [rails-rest-framework.com](https://rails-rest-framework.com)
18
+
19
+ Demo API: [rails-rest-framework.com/api/demo](https://rails-rest-framework.com/api/demo)
20
+
21
+ Source: [github.com/gregschmit/rails-rest-framework](https://github.com/gregschmit/rails-rest-framework)
22
+
23
+ YARD Docs: [rubydoc.info/gems/rest_framework](https://rubydoc.info/gems/rest_framework)
24
+
25
+ ## Installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ ```ruby
30
+ gem 'rest_framework'
31
+ ```
32
+
33
+ And then execute:
34
+
35
+ ```shell
36
+ $ bundle install
37
+ ```
38
+
39
+ Or install it yourself with:
40
+
41
+ ```shell
42
+ $ gem install rest_framework
43
+ ```
44
+
45
+ ## Quick Usage Tutorial
46
+
47
+ ### Controller Mixins
48
+
49
+ To transform a controller into a RESTful controller, you can either include `BaseControllerMixin`,
50
+ `ReadOnlyModelControllerMixin`, or `ModelControllerMixin`. `BaseControllerMixin` provides a `root`
51
+ action and a simple interface for routing arbitrary additional actions:
52
+
53
+ ```ruby
54
+ class ApiController < ApplicationController
55
+ include RESTFramework::BaseControllerMixin
56
+ self.extra_actions = {test: :get}
57
+
58
+ def test
59
+ render api_response({message: "Test successful!"})
60
+ end
61
+ end
62
+ ```
63
+
64
+ `ModelControllerMixin` assists with providing the standard model CRUD for your controller.
65
+
66
+ ```ruby
67
+ class Api::MoviesController < ApiController
68
+ include RESTFramework::ModelControllerMixin
69
+
70
+ self.recordset = Movie.where(enabled: true)
71
+ end
72
+ ```
73
+
74
+ `ReadOnlyModelControllerMixin` only enables list/show actions, but since we're naming this
75
+ controller in a way that doesn't make the model obvious, we can set that explicitly:
76
+
77
+ ```ruby
78
+ class Api::ReadOnlyMoviesController < ApiController
79
+ include RESTFramework::ReadOnlyModelControllerMixin
80
+
81
+ self.model = Movie
82
+ end
83
+ ```
84
+
85
+ Note that you can also override the `get_recordset` instance method to override the API behavior
86
+ dynamically per-request.
87
+
88
+ ### Routing
89
+
90
+ You can use Rails' `resource`/`resources` routers to route your API, however if you want
91
+ `extra_actions` / `extra_member_actions` to be routed automatically, then you can use `rest_route`
92
+ for non-resourceful controllers, or `rest_resource` / `rest_resources` resourceful routers. You can
93
+ also use `rest_root` to route the root of your API:
94
+
95
+ ```ruby
96
+ Rails.application.routes.draw do
97
+ rest_root :api # will find `api_controller` and route the `root` action to '/api'
98
+ namespace :api do
99
+ rest_resources :movies
100
+ rest_resources :users
101
+ end
102
+ end
103
+ ```
104
+
105
+ Or if you want the API root to be routed to `Api::RootController#root`:
106
+
107
+ ```ruby
108
+ Rails.application.routes.draw do
109
+ namespace :api do
110
+ rest_root # will route `Api::RootController#root` to '/' in this namespace ('/api')
111
+ rest_resources :movies
112
+ rest_resources :users
113
+ end
114
+ end
115
+ ```
116
+
117
+ ## Development/Testing
118
+
119
+ After you clone the repository, cd'ing into the directory should create a new gemset if you are
120
+ using RVM. Then run `bundle install` to install the appropriate gems.
121
+
122
+ To run the test suite:
123
+
124
+ ```shell
125
+ $ rails test
126
+ ```
127
+
128
+ The top-level `bin/rails` proxies all Rails commands to the test project, so you can operate it via
129
+ the usual commands. Ensure you run `rails db:setup` before running `rails server` or
130
+ `rails console`.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.4
1
+ 0.9.6
@@ -8,195 +8,21 @@
8
8
  <%= csp_meta_tag rescue nil %>
9
9
 
10
10
  <%= render partial: "rest_framework/head", cached: true %>
11
+
12
+ <%= yield :head %>
11
13
  </head>
12
14
 
13
15
  <body>
14
16
  <header>
15
- <div class="w-100 m-0 p-0" id="rrfAccentBar"></div>
16
- <nav class="navbar py-0" data-bs-theme="dark">
17
- <div class="container">
18
- <span class="navbar-brand p-0">
19
- <h1 title="RRF v<%= RESTFramework::VERSION %>" class="text-light font-weight-light m-0 p-0" style="font-size: 1em">
20
- <%= @template_logo_text || "Rails REST Framework" %>
21
- </h1>
22
- </span>
23
- <div class="dropdown ms-auto" id="rrfModeComponent">
24
- <button class="btn btn-dark dropdown-toggle rounded-0 bg-black" style="border-color: black" data-bs-toggle="dropdown"></button>
25
- <div class="rrf-mode dropdown-menu dropdown-menu-end py-0 rounded-0" style="font-size: .8em; min-width: 0">
26
- <button class="dropdown-item text-end" data-rrf-mode-value="system">
27
- System<i class="bi bi-circle-half ms-2"></i>
28
- </button>
29
- <button class="dropdown-item text-end" data-rrf-mode-value="light">
30
- Light<i class="bi bi-sun-fill ms-2"></i>
31
- </button>
32
- <button class="dropdown-item text-end" data-rrf-mode-value="dark">
33
- Dark<i class="bi bi-moon-stars-fill ms-2"></i>
34
- </button>
35
- </div>
36
- </div>
37
- </div>
38
- </nav>
17
+ <%= render partial: "rest_framework/header" %>
39
18
  </header>
40
19
  <div class="container py-3">
41
- <div class="row">
42
- <nav>
43
- <ol class="breadcrumb">
44
- <%
45
- breadcrumbs = request.path.split("/").inject([]) { |breadcrumbs, part|
46
- # Ignore blank parts of the path (leading slash or double-slashes).
47
- next breadcrumbs if part.blank?
48
-
49
- last_path = breadcrumbs.last&.first || "/"
50
- breadcrumbs << [
51
- [last_path, part].join(last_path[-1] == "/" ? "" : "/"),
52
- part,
53
- ]
54
-
55
- next breadcrumbs
56
- }
57
- %>
58
- <% breadcrumbs.each_with_index do |(path, label), i| %>
59
- <% if i != breadcrumbs.size - 1 %>
60
- <li class="breadcrumb-item"><a href="<%= path %>"><%= label %></a></li>
61
- <% else %>
62
- <li class="breadcrumb-item active"><%= label %></li>
63
- <% end %>
64
- <% end %>
65
- </ol>
66
- </nav>
67
- </div>
68
- <div class="row">
69
- <div>
70
- <h1 class="m-0"><%= (@header_text if defined? @header_text) || @title %></h1>
71
- <div style="float: right">
72
- <% if @route_groups.values[0].any? { |r| r[:matches_path] && r[:verb] == "DELETE" && r[:action] == "destroy" } %>
73
- <button type="button" class="btn btn-danger" onclick="rrfDelete(this)">DELETE</button>
74
- <% end %>
75
- <% if @route_groups.values[0].any? { |r| r[:matches_path] && r[:verb] == "OPTIONS" } %>
76
- <button type="button" class="btn btn-primary" onclick="rrfOptions(this)">OPTIONS</button>
77
- <% end %>
78
- <button type="button" class="btn btn-primary" onclick="rrfGet(this)">GET</button>
79
- </div>
80
- <% if @description.present? %>
81
- <br><br><p style="display: inline-block; margin-bottom: 0"><%= @description %></p>
82
- <% end %>
83
- </div>
84
- </div>
85
- <hr/>
86
- <div class="row">
87
- <div>
88
- <pre style="white-space: normal">
89
- <code>
90
- <strong>
91
- <%= request.request_method %>
92
- <% if request.method != request.request_method %>
93
- (via <%= request.method %>)
94
- <% end %>
95
- </strong> <%= request.path %><br>
96
- </code>
97
- </pre>
98
- <pre style="white-space: normal">
99
- <code>
100
- <strong>HTTP <%= response.status %> <%= response.message %></strong><br>
101
- <strong>Content-Type:</strong> <%= response.content_type %>
102
- </code>
103
- </pre>
104
- </div>
105
- </div>
106
- <% if @json_payload.present? || @xml_payload.present? %>
107
- <div class="row">
108
- <div>
109
- <ul class="nav nav-tabs">
110
- <% if @json_payload.present? %>
111
- <li class="nav-item">
112
- <a class="nav-link active" href="#tab-json" data-bs-toggle="tab" role="tab">
113
- .json
114
- </a>
115
- </li>
116
- <% end %>
117
- <% if @xml_payload.present? %>
118
- <li class="nav-item">
119
- <a class="nav-link" href="#tab-xml" data-bs-toggle="tab" role="tab">
120
- .xml
121
- </a>
122
- </li>
123
- <% end %>
124
- </ul>
125
- </div>
126
- <div class="tab-content pt-2">
127
- <div class="tab-pane fade show active" id="tab-json" role="tabpanel">
128
- <% if @json_payload.present? %>
129
- <div><pre class="rrf-copy"><code class="auto-hljs language-json"><%=
130
- JSON.pretty_generate(
131
- JSON.parse(@json_payload)
132
- ) unless @json_payload == ''
133
- %></code></pre></div>
134
- <% end %>
135
- </div>
136
- <div class="tab-pane fade" id="tab-xml" role="tabpanel">
137
- <% if @xml_payload.present? %>
138
- <div><pre class="rrf-copy"><code class="auto-hljs language-xml"><%=
139
- CGI.unescapeHTML(@xml_payload)
140
- %></code></pre></div>
141
- <% end %>
142
- </div>
143
- </div>
144
- </div>
145
- <% end %>
146
- <% if @route_groups.present? %>
147
- <%
148
- @is_model_controller = controller.class.included_modules.include?(RESTFramework::ModelControllerMixin)
149
- %>
150
- <div class="row">
151
- <div>
152
- <ul class="nav nav-tabs">
153
- <li class="nav-item">
154
- <a class="nav-link active" href="#tab-routes" data-bs-toggle="tab" role="tab">
155
- Routes
156
- </a>
157
- </li>
158
- <% @_rrf_form_routes_raw = @route_groups.values[0].select { |r|
159
- r[:matches_params] && (
160
- r[:verb].in?(["POST", "PUT", "PATCH"]) ||
161
- (r[:verb] == "DELETE" && r[:action] == "destroy_all")
162
- )
163
- } %>
164
- <% @_rrf_form_routes_html = @route_groups.values[0].select { |r|
165
- r[:matches_params] && r[:verb].in?(["POST", "PUT", "PATCH"])
166
- } %>
167
- <% if @_rrf_form_routes_raw.present? %>
168
- <li class="nav-item">
169
- <a class="nav-link" href="#tabRawForm" data-bs-toggle="tab" role="tab">
170
- Raw Form
171
- </a>
172
- </li>
173
- <% end %>
174
- <% if @_rrf_form_routes_html.present? && @is_model_controller %>
175
- <li class="nav-item">
176
- <a class="nav-link" href="#tabHtmlForm" data-bs-toggle="tab" role="tab">
177
- HTML Form
178
- </a>
179
- </li>
180
- <% end %>
181
- </ul>
182
- </div>
183
- <div class="tab-content pt-2">
184
- <div class="tab-pane fade show active" id="tab-routes" role="tabpanel">
185
- <%= render partial: "rest_framework/routes" %>
186
- </div>
187
- <% if @_rrf_form_routes_raw.present? %>
188
- <div class="tab-pane fade" id="tabRawForm" role="tabpanel">
189
- <%= render partial: "rest_framework/raw_form" %>
190
- </div>
191
- <% end %>
192
- <% if @_rrf_form_routes_html.present? && @is_model_controller %>
193
- <div class="tab-pane fade" id="tabHtmlForm" role="tabpanel">
194
- <%= render partial: "rest_framework/html_form" %>
195
- </div>
196
- <% end %>
197
- </div>
198
- </div>
199
- <% end %>
20
+ <%= render partial: "rest_framework/breadcrumbs" unless @hide_breadcrumbs %>
21
+ <%= render partial: "rest_framework/heading" unless @hide_heading %>
22
+ <%= render partial: "rest_framework/request_metadata" unless @hide_request_metadata %>
23
+ <%= yield %>
24
+ <%= render partial: "rest_framework/payloads" if @json_payload.present? || @xml_payload.present? %>
25
+ <%= render partial: "rest_framework/routes_and_forms" if @route_groups.present? %>
200
26
  </div>
201
27
  </body>
202
28
  </html>
@@ -0,0 +1,27 @@
1
+ <div class="row">
2
+ <nav>
3
+ <ol class="breadcrumb">
4
+ <%
5
+ breadcrumbs = request.path.split("/").inject([]) { |breadcrumbs, part|
6
+ # Ignore blank parts of the path (leading slash or double-slashes).
7
+ next breadcrumbs if part.blank?
8
+
9
+ last_path = breadcrumbs.last&.first || "/"
10
+ breadcrumbs << [
11
+ [last_path, part].join(last_path[-1] == "/" ? "" : "/"),
12
+ part,
13
+ ]
14
+
15
+ next breadcrumbs
16
+ }
17
+ %>
18
+ <% breadcrumbs.each_with_index do |(path, label), i| %>
19
+ <% if i != breadcrumbs.size - 1 %>
20
+ <li class="breadcrumb-item"><a href="<%= path %>"><%= label %></a></li>
21
+ <% else %>
22
+ <li class="breadcrumb-item active"><%= label %></li>
23
+ <% end %>
24
+ <% end %>
25
+ </ol>
26
+ </nav>
27
+ </div>