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
@@ -1,155 +0,0 @@
1
- <head>
2
- <meta charset="utf-8">
3
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
4
- <link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico" />
5
-
6
- <title>{% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}</title>
7
-
8
- {% include external.html %}
9
- {% include shared.html %}
10
-
11
- <style>
12
- /* Header adjustments. */
13
- h1, h2, h3, h4, h5, h6 {
14
- width: 100%;
15
- font-weight: normal;
16
- margin-top: 1.8rem;
17
- margin-bottom: 1.2rem;
18
- }
19
- h1 a:not(:hover),
20
- h2 a:not(:hover),
21
- h3 a:not(:hover),
22
- h4 a:not(:hover),
23
- h5 a:not(:hover),
24
- h6 a:not(:hover) {
25
- color: #ddd;
26
- }
27
- html[data-bs-theme="dark"] h1 a:not(:hover),
28
- html[data-bs-theme="dark"] h2 a:not(:hover),
29
- html[data-bs-theme="dark"] h3 a:not(:hover),
30
- html[data-bs-theme="dark"] h4 a:not(:hover),
31
- html[data-bs-theme="dark"] h5 a:not(:hover),
32
- html[data-bs-theme="dark"] h6 a:not(:hover) {
33
- color: #444;
34
- }
35
- h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover {
36
- text-decoration: none !important;
37
- }
38
-
39
- /* Navbar */
40
- .navbar .navbar-toggler {
41
- margin: .2em 0;
42
- padding: .2em .3em;
43
- border: none;
44
- }
45
- .navbar .navbar-toggler .navbar-toggler-icon {
46
- height: 1.1em;
47
- width: 1.1em;
48
- }
49
- .navbar .navbar-nav .nav-item .nav-link {
50
- padding: .45em .6em;
51
- }
52
- .navbar .navbar-nav .nav-item .nav-link:hover {
53
- background-color: #262a2f;
54
- }
55
- .navbar .dropdown-menu a.dropdown-item {
56
- font-size: .9em;
57
- padding: .2em .8em;
58
- }
59
-
60
- /* Headers table. */
61
- .headers-table {
62
- padding: .5em 1em;
63
- background-color: #eee;
64
- border: 1px solid #aaa;
65
- border-radius: .3em;
66
- font-size: .9em;
67
- }
68
- html[data-bs-theme="dark"] .headers-table {
69
- background-color: #2b2b2b;
70
- }
71
- .headers-table:empty { display: none; }
72
- .headers-table ul {
73
- list-style-type: none;
74
- margin: 0;
75
- padding-left: 0;
76
- padding-right: .6em;
77
- }
78
- .headers-table ul li { margin: .3em 0; }
79
- .headers-table ul ul { padding-left: .8em; padding-right: 0; }
80
- .headers-table > ul > li {
81
- font-weight: bold;
82
- }
83
-
84
- /* Style the github and mode component. */
85
- #rrfGithubAndModeWrapper {
86
- height: 2.4em;
87
- }
88
- #rrfGithubComponent {
89
- display: inline-block;
90
- position: relative;
91
- top: .6em;
92
- }
93
- #rrfModeComponent .dropdown-toggle {
94
- float: right;
95
- }
96
- #rrfModeComponent .dropdown-menu {
97
- position: absolute;
98
- right: 0;
99
- left: auto;
100
- top: 100%;
101
- }
102
- </style>
103
-
104
- <script>
105
- document.addEventListener("DOMContentLoaded", () => {
106
- // Initialize `Highlight.js`.
107
- hljs.configure({ ignoreUnescapedHTML: true })
108
- hljs.highlightAll()
109
-
110
- // Setup the floating table of contents.
111
- let table = "<ul>"
112
- let hlevel = 2
113
- let hprevlevel = 2
114
- document.querySelectorAll("h2, h3, h4").forEach((header) => {
115
- hlevel = parseInt(header.tagName[1])
116
-
117
- if (hlevel > hprevlevel) {
118
- table += "<ul>"
119
- } else if (hlevel < hprevlevel) {
120
- Array(hprevlevel - hlevel)
121
- .fill(0)
122
- .forEach(function () {
123
- table += "</ul>"
124
- })
125
- }
126
- table += `<li><a href="${
127
- header.querySelectorAll("a")[0].href
128
- }">${header.childNodes[0].nodeValue.trim()}</a></li>`
129
- hprevlevel = hlevel
130
- })
131
- if (hlevel > hprevlevel) {
132
- table += "</ul>"
133
- }
134
- table += "</ul>"
135
- if (table != "<ul></ul>") {
136
- document.getElementById("headersTable").innerHTML = table
137
- }
138
- })
139
- </script>
140
-
141
- <!-- Extra Highlight.js languages not shared with the library. -->
142
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/shell.min.js" integrity="sha512-X2JngetHwVsp0j3n6lo8HGdXQKLpz2hwFfQkG996OfanpFaQJFgjKJlmzsdefWsHTQIwY539tD09JF48kCPMXw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
143
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/erb.min.js" integrity="sha512-flbEiCcectGeyRXyuMZW5jlAGIQ1/qrTZS6DsZDTqObM0JG/isYHvUyehOyt14ssmY85gZRYra+IJR9+azRuqw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
144
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/ruby.min.js" integrity="sha512-xRUQANk9Iw3wtAp0cBOa1Ghr7yIFrMiJiEujrMGf04qOau23exxj4R7DLUeLGfLiDbVSK0FyN8v2ns4m/6iNmQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
145
-
146
- <!-- Google Analytics: Global Site Tag -->
147
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-P2KRPNXQMT"></script>
148
- <script>
149
- window.dataLayer = window.dataLayer || [];
150
- function gtag(){dataLayer.push(arguments);}
151
- gtag('js', new Date());
152
-
153
- gtag('config', 'G-P2KRPNXQMT');
154
- </script>
155
- </head>
@@ -1,58 +0,0 @@
1
- <header>
2
- <div class="w-100 m-0 p-0" id="rrfAccentBar"></div>
3
- <nav class="navbar py-0 navbar-expand-md" data-bs-theme="dark">
4
- <div class="container">
5
-
6
- <span class="navbar-brand p-0">
7
- <a href="/">
8
- <h1 class="text-light font-weight-light m-0 p-0" style="font-size: 1em; ">{{ site.title }}</h1>
9
- </a>
10
- </span>
11
-
12
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent">
13
- <span class="navbar-toggler-icon"></span>
14
- </button>
15
-
16
- <div class="collapse navbar-collapse" id="navbarSupportedContent">
17
- <ul class="navbar-nav ms-auto">
18
- <li class="nav-item">
19
- <a class="nav-link{% if page.url == '/' %} active{% endif %}" href="/">Home</a>
20
- </li>
21
-
22
- <li class="nav-item dropdown">
23
- <a class="nav-link dropdown-toggle {% if page.url contains 'guide' %} active{% endif %}" href="#" role="button" data-bs-toggle="dropdown">
24
- Guide
25
- </a>
26
- <div class="rrf-mode dropdown-menu">
27
- {% for section in site.guide %}
28
- <a class="dropdown-item" href="{{ section.url }}">{{ section.title }}</a>
29
- {% endfor %}
30
- </div>
31
- </li>
32
-
33
- <li class="nav-item ps-2" id="rrfGithubAndModeWrapper">
34
- <span id="rrfGithubComponent">
35
- <script async defer src="https://buttons.github.io/buttons.js"></script>
36
- <a class="github-button" href="https://github.com/gregschmit/rails-rest-framework" data-show-count="true" aria-label="Star gregschmit/rails-rest-framework on GitHub">Star</a>
37
- </span>
38
- <div class="dropdown ms-auto float-end" id="rrfModeComponent">
39
- <button class="btn btn-dark dropdown-toggle rounded-0 bg-black" style="border-color: black" data-bs-toggle="dropdown"></button>
40
- <div class="rrf-mode dropdown-menu dropdown-menu-end py-0 rounded-0" style="font-size: .8em; min-width: 0">
41
- <button class="dropdown-item text-end" data-rrf-mode-value="system">
42
- System<i class="bi bi-circle-half ms-2"></i>
43
- </button>
44
- <button class="dropdown-item text-end" data-rrf-mode-value="light">
45
- Light<i class="bi bi-sun-fill ms-2"></i>
46
- </button>
47
- <button class="dropdown-item text-end" data-rrf-mode-value="dark">
48
- Dark<i class="bi bi-moon-stars-fill ms-2"></i>
49
- </button>
50
- </div>
51
- </div>
52
- </li>
53
- </ul>
54
- </div>
55
-
56
- </div>
57
- </nav>
58
- </header>
@@ -1,164 +0,0 @@
1
- <!--
2
- AUTOGENERATED
3
- Updates must be written to `shared.{css,js}` and synced with `rake maintain_assets`.
4
- -->
5
- <style>
6
- :root {
7
- --rrf-red: #900;
8
- --rrf-red-hover: #5f0c0c;
9
- --rrf-light-red: #db2525;
10
- --rrf-light-red-hover: #b80404;
11
- }
12
- #rrfAccentBar {
13
- background-color: var(--rrf-red);
14
- height: .3em;
15
- }
16
- header nav { background-color: black; }
17
-
18
- /* Header adjustments. */
19
- h1 { font-size: 2rem; }
20
- h2 { font-size: 1.7rem; }
21
- h3 { font-size: 1.5rem; }
22
- h4 { font-size: 1.3rem; }
23
- h5 { font-size: 1.1rem; }
24
- h6 { font-size: 1rem; }
25
- h1, h2, h3, h4, h5, h6 {
26
- color: var(--rrf-red);
27
- }
28
- html[data-bs-theme="dark"] h1,
29
- html[data-bs-theme="dark"] h2,
30
- html[data-bs-theme="dark"] h3,
31
- html[data-bs-theme="dark"] h4,
32
- html[data-bs-theme="dark"] h5,
33
- html[data-bs-theme="dark"] h6 {
34
- color: var(--rrf-light-red);
35
- }
36
-
37
- /* Improve code and code blocks. */
38
- pre code, .trix-content pre {
39
- display: block;
40
- overflow-x: auto;
41
- padding: .5em !important;
42
- }
43
- code, .trix-content pre {
44
- --bs-code-color: black;
45
- background-color: #eee !important;
46
- border: 1px solid #aaa;
47
- border-radius: 3px;
48
- padding: .1em .3em;
49
- }
50
- html[data-bs-theme="dark"] code, html[data-bs-theme="dark"] .trix-content pre {
51
- --bs-code-color: white;
52
- background-color: #2b2b2b !important;
53
- }
54
-
55
- /* Anchors */
56
- a:not(.nav-link) {
57
- text-decoration: none;
58
- color: var(--rrf-red);
59
- }
60
- a:hover:not(.nav-link) {
61
- text-decoration: underline;
62
- color: var(--rrf-red-hover);
63
- }
64
- html[data-bs-theme="dark"] a:not(.nav-link) { color: var(--rrf-light-red); }
65
- html[data-bs-theme="dark"] a:hover:not(.nav-link) { color: var(--rrf-light-red-hover); }
66
-
67
- </style>
68
- <script>
69
- ;(() => {
70
- // Get the real mode from a selected mode. Anything other than "light" or "dark" is treated as
71
- // "system" mode.
72
- const rrfGetRealMode = (selectedMode) => {
73
- if (selectedMode === "light" || selectedMode === "dark") {
74
- return selectedMode
75
- }
76
-
77
- if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
78
- return "dark"
79
- }
80
-
81
- return "light"
82
- }
83
-
84
- // Set the mode, given a "selected" mode.
85
- const rrfSetSelectedMode = (selectedMode) => {
86
- // Anything except "light" or "dark" is casted to "system".
87
- if (selectedMode !== "light" && selectedMode !== "dark") {
88
- selectedMode = "system"
89
- }
90
-
91
- // Store selected mode in `localStorage`.
92
- localStorage.setItem("rrfMode", selectedMode)
93
-
94
- // Set the mode selector to the selected mode.
95
- const modeComponent = document.getElementById("rrfModeComponent")
96
- if (modeComponent) {
97
- let labelHTML
98
- modeComponent.querySelectorAll("button[data-rrf-mode-value]").forEach((el) => {
99
- if (el.getAttribute("data-rrf-mode-value") === selectedMode) {
100
- el.classList.add("active")
101
- labelHTML = el.querySelector("i").outerHTML.replace("ms-2", "me-1")
102
- } else {
103
- el.classList.remove("active")
104
- }
105
- })
106
- modeComponent.querySelector("button[data-bs-toggle]").innerHTML = labelHTML
107
- }
108
-
109
- // Get the real mode to use.
110
- realMode = rrfGetRealMode(selectedMode)
111
-
112
- // Set the `realMode` effects.
113
- if (realMode === "light") {
114
- document.querySelectorAll(".rrf-light-mode").forEach((el) => {
115
- el.disabled = false
116
- })
117
- document.querySelectorAll(".rrf-dark-mode").forEach((el) => {
118
- el.disabled = true
119
- })
120
- document.querySelectorAll(".rrf-mode").forEach((el) => {
121
- el.setAttribute("data-bs-theme", "light")
122
- })
123
- } else if (realMode === "dark") {
124
- document.querySelectorAll(".rrf-light-mode").forEach((el) => {
125
- el.disabled = true
126
- })
127
- document.querySelectorAll(".rrf-dark-mode").forEach((el) => {
128
- el.disabled = false
129
- })
130
- document.querySelectorAll(".rrf-mode").forEach((el) => {
131
- el.setAttribute("data-bs-theme", "dark")
132
- })
133
- } else {
134
- console.log(`RRF: Unknown mode: ${mode}`)
135
- }
136
- }
137
-
138
- // Initialize dark/light mode before page fully loads to prevent flash.
139
- rrfSetSelectedMode(localStorage.getItem("rrfMode"))
140
-
141
- // Initialize dark/light mode after page load (mostly so mode component is updated).
142
- document.addEventListener("DOMContentLoaded", (event) => {
143
- rrfSetSelectedMode(localStorage.getItem("rrfMode"))
144
-
145
- // Also set up mode selector.
146
- document.querySelectorAll("#rrfModeComponent button[data-rrf-mode-value]").forEach((el) => {
147
- el.addEventListener("click", (event) => {
148
- rrfSetSelectedMode(event.target.getAttribute("data-rrf-mode-value"))
149
- })
150
- })
151
- })
152
-
153
- // Handle case where user changes system theme.
154
- if (window.matchMedia) {
155
- window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
156
- const selectedMode = localStorage.getItem("rrfMode")
157
- if (selectedMode !== "light" && selectedMode !== "dark") {
158
- rrfSetSelectedMode("system")
159
- }
160
- })
161
- }
162
- })()
163
-
164
- </script>
@@ -1,11 +0,0 @@
1
- <!DOCTYPE html>
2
- <html class="rrf-mode">
3
- {% include head.html %}
4
- <body>
5
- {% include header.html %}
6
- <div class="container pb-3">
7
- <div id="headersTable" class="headers-table float-md-end m-2"></div>
8
- {% include anchor_headings.html html=content anchorBody="#" %}
9
- </div>
10
- </body>
11
- </html>
Binary file
data/docs/index.md DELETED
@@ -1,133 +0,0 @@
1
- ---
2
- ---
3
-
4
- # Rails REST Framework
5
-
6
- [![Gem Version](https://badge.fury.io/rb/rest_framework.svg)](https://badge.fury.io/rb/rest_framework)
7
- [![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)
8
- [![Coverage](https://coveralls.io/repos/github/gregschmit/rails-rest-framework/badge.svg?branch=master)](https://coveralls.io/github/gregschmit/rails-rest-framework?branch=master)
9
- [![Maintainability](https://api.codeclimate.com/v1/badges/ba5df7706cb544d78555/maintainability)](https://codeclimate.com/github/gregschmit/rails-rest-framework/maintainability)
10
-
11
- A framework for DRY RESTful APIs in Ruby on Rails.
12
-
13
- **The Problem**: Building controllers for APIs usually involves writing a lot of redundant CRUD
14
- logic, and routing them can be obnoxious. Building and maintaining features like ordering,
15
- filtering, and pagination can be tedious.
16
-
17
- **The Solution**: This framework implements browsable API responses, CRUD actions for your models,
18
- and features like ordering/filtering/pagination, so you can focus on building awesome APIs.
19
-
20
- Website/Guide: [rails-rest-framework.com](https://rails-rest-framework.com)
21
-
22
- Demo: [demo.rails-rest-framework.com](https://demo.rails-rest-framework.com)
23
-
24
- Source: [github.com/gregschmit/rails-rest-framework](https://github.com/gregschmit/rails-rest-framework)
25
-
26
- YARD Docs: [rubydoc.info/gems/rest_framework](https://rubydoc.info/gems/rest_framework)
27
-
28
- ## Installation
29
-
30
- Add this line to your application's Gemfile:
31
-
32
- ```ruby
33
- gem 'rest_framework'
34
- ```
35
-
36
- And then execute:
37
-
38
- ```shell
39
- $ bundle install
40
- ```
41
-
42
- Or install it yourself with:
43
-
44
- ```shell
45
- $ gem install rest_framework
46
- ```
47
-
48
- ## Quick Usage Tutorial
49
-
50
- ### Controller Mixins
51
-
52
- To transform a controller into a RESTful controller, you can either include `BaseControllerMixin`,
53
- `ReadOnlyModelControllerMixin`, or `ModelControllerMixin`. `BaseControllerMixin` provides a `root`
54
- action and a simple interface for routing arbitrary additional actions:
55
-
56
- ```ruby
57
- class ApiController < ApplicationController
58
- include RESTFramework::BaseControllerMixin
59
- self.extra_actions = {test: [:get]}
60
-
61
- def test
62
- render api_response({message: "Test successful!"})
63
- end
64
- end
65
- ```
66
-
67
- `ModelControllerMixin` assists with providing the standard model CRUD for your controller.
68
-
69
- ```ruby
70
- class Api::MoviesController < ApiController
71
- include RESTFramework::ModelControllerMixin
72
-
73
- self.recordset = Movie.where(enabled: true)
74
- end
75
- ```
76
-
77
- `ReadOnlyModelControllerMixin` only enables list/show actions, but since we're naming this
78
- controller in a way that doesn't make the model obvious, we can set that explicitly:
79
-
80
- ```ruby
81
- class Api::ReadOnlyMoviesController < ApiController
82
- include RESTFramework::ReadOnlyModelControllerMixin
83
-
84
- self.model = Movie
85
- end
86
- ```
87
-
88
- Note that you can also override the `get_recordset` instance method to override the API behavior
89
- dynamically per-request.
90
-
91
- ### Routing
92
-
93
- You can use Rails' `resource`/`resources` routers to route your API, however if you want
94
- `extra_actions` / `extra_member_actions` to be routed automatically, then you can use `rest_route`
95
- for non-resourceful controllers, or `rest_resource` / `rest_resources` resourceful routers. You can
96
- also use `rest_root` to route the root of your API:
97
-
98
- ```ruby
99
- Rails.application.routes.draw do
100
- rest_root :api # will find `api_controller` and route the `root` action to '/api'
101
- namespace :api do
102
- rest_resources :movies
103
- rest_resources :users
104
- end
105
- end
106
- ```
107
-
108
- Or if you want the API root to be routed to `Api::RootController#root`:
109
-
110
- ```ruby
111
- Rails.application.routes.draw do
112
- namespace :api do
113
- rest_root # will route `Api::RootController#root` to '/' in this namespace ('/api')
114
- rest_resources :movies
115
- rest_resources :users
116
- end
117
- end
118
- ```
119
-
120
- ## Development/Testing
121
-
122
- After you clone the repository, cd'ing into the directory should create a new gemset if you are
123
- using RVM. Then run `bundle install` to install the appropriate gems.
124
-
125
- To run the test suite:
126
-
127
- ```shell
128
- $ rails test
129
- ```
130
-
131
- The top-level `bin/rails` proxies all Rails commands to the test project, so you can operate it via
132
- the usual commands. Ensure you run `rails db:setup` before running `rails server` or
133
- `rails console`.