rest_framework 0.9.4 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +130 -0
- data/VERSION +1 -1
- data/app/views/layouts/rest_framework.html.erb +9 -183
- data/app/views/rest_framework/_breadcrumbs.html.erb +27 -0
- data/app/views/rest_framework/_head.html.erb +348 -190
- data/app/views/rest_framework/_header.html.erb +15 -0
- data/app/views/rest_framework/_heading.html.erb +10 -0
- data/app/views/rest_framework/_payloads.html.erb +36 -0
- data/app/views/rest_framework/_request_metadata.html.erb +16 -0
- data/app/views/rest_framework/_routes_and_forms.html.erb +52 -0
- data/app/views/rest_framework/head/_external.html.erb +7 -2
- data/app/views/rest_framework/header/_mode.html.erb +14 -0
- data/app/views/rest_framework/heading/_actions.html.erb +9 -0
- data/app/views/rest_framework/{_routes.html.erb → routes_and_forms/_routes.html.erb} +2 -2
- data/lib/rest_framework/controller_mixins/base.rb +11 -12
- data/lib/rest_framework/engine.rb +5 -3
- data/lib/rest_framework/filters/ransack.rb +6 -6
- data/lib/rest_framework/version.rb +0 -6
- data/lib/rest_framework.rb +25 -13
- data/vendor/assets/javascripts/rest_framework/external.min.js +1256 -0
- data/vendor/assets/stylesheets/rest_framework/{bootstrap-icons.css → external.min.css} +415 -1
- data/vendor/assets/stylesheets/rest_framework/{highlight-a11y-dark.css → highlight-a11y-dark.min.css} +1 -1
- data/vendor/assets/stylesheets/rest_framework/{highlight-a11y-light.css → highlight-a11y-light.min.css} +1 -1
- metadata +18 -35
- data/README.md +0 -1
- data/app/views/rest_framework/head/_shared.html +0 -164
- data/docs/CNAME +0 -1
- data/docs/Gemfile +0 -5
- data/docs/Gemfile.lock +0 -264
- data/docs/_config.yml +0 -19
- data/docs/_guide/1_routers.md +0 -110
- data/docs/_guide/2_controllers.md +0 -342
- data/docs/_guide/3_serializers.md +0 -60
- data/docs/_guide/4_filtering_and_ordering.md +0 -41
- data/docs/_guide/5_pagination.md +0 -21
- data/docs/_includes/anchor_headings.html +0 -144
- data/docs/_includes/external.html +0 -9
- data/docs/_includes/head.html +0 -155
- data/docs/_includes/header.html +0 -58
- data/docs/_includes/shared.html +0 -164
- data/docs/_layouts/default.html +0 -11
- data/docs/assets/images/favicon.ico +0 -0
- data/docs/index.md +0 -133
- data/vendor/assets/javascripts/rest_framework/bootstrap.js +0 -7
- data/vendor/assets/javascripts/rest_framework/highlight-json.js +0 -7
- data/vendor/assets/javascripts/rest_framework/highlight-xml.js +0 -29
- data/vendor/assets/javascripts/rest_framework/highlight.js +0 -1202
- data/vendor/assets/javascripts/rest_framework/neatjson.js +0 -8
- data/vendor/assets/javascripts/rest_framework/trix.js +0 -6
- data/vendor/assets/stylesheets/rest_framework/bootstrap.css +0 -6
- data/vendor/assets/stylesheets/rest_framework/trix.css +0 -410
- /data/app/views/rest_framework/{_html_form.html.erb → routes_and_forms/_html_form.html.erb} +0 -0
- /data/app/views/rest_framework/{_raw_form.html.erb → routes_and_forms/_raw_form.html.erb} +0 -0
- /data/app/views/rest_framework/{_route.html.erb → routes_and_forms/routes/_route.html.erb} +0 -0
data/docs/_includes/head.html
DELETED
@@ -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>
|
data/docs/_includes/header.html
DELETED
@@ -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>
|
data/docs/_includes/shared.html
DELETED
@@ -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>
|
data/docs/_layouts/default.html
DELETED
@@ -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`.
|