compony 0.11.8 → 0.11.9
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/.yardopts +36 -1
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +85 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -3
- data/VERSION +1 -1
- data/compony.gemspec +3 -3
- data/doc/ComponentGenerator.html +1 -1
- data/doc/Components.html +1 -1
- data/doc/ComponentsGenerator.html +1 -1
- data/doc/Compony/Component.html +54 -54
- data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +109 -70
- data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +64 -28
- data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
- data/doc/Compony/ComponentMixins/Default.html +1 -1
- data/doc/Compony/ComponentMixins/Resourceful.html +213 -74
- data/doc/Compony/ComponentMixins.html +1 -1
- data/doc/Compony/Components/Buttons/CssButton.html +1 -1
- data/doc/Compony/Components/Buttons/Link.html +1 -1
- data/doc/Compony/Components/Buttons.html +1 -1
- data/doc/Compony/Components/Destroy.html +83 -29
- data/doc/Compony/Components/Edit.html +110 -38
- data/doc/Compony/Components/Form.html +551 -208
- data/doc/Compony/Components/Index.html +1 -1
- data/doc/Compony/Components/List.html +3 -3
- data/doc/Compony/Components/New.html +110 -38
- data/doc/Compony/Components/Show.html +1 -1
- data/doc/Compony/Components/WithForm.html +194 -47
- data/doc/Compony/Components.html +1 -1
- data/doc/Compony/ControllerMixin.html +1 -1
- data/doc/Compony/Engine.html +1 -1
- data/doc/Compony/Intent.html +2 -2
- data/doc/Compony/ManageIntentsDsl.html +1 -1
- data/doc/Compony/MethodAccessibleHash.html +1 -1
- data/doc/Compony/ModelFields/Anchormodel.html +1 -1
- data/doc/Compony/ModelFields/Association.html +1 -1
- data/doc/Compony/ModelFields/Attachment.html +1 -1
- data/doc/Compony/ModelFields/Base.html +1 -1
- data/doc/Compony/ModelFields/Boolean.html +1 -1
- data/doc/Compony/ModelFields/Color.html +1 -1
- data/doc/Compony/ModelFields/Currency.html +1 -1
- data/doc/Compony/ModelFields/Date.html +1 -1
- data/doc/Compony/ModelFields/Datetime.html +1 -1
- data/doc/Compony/ModelFields/Decimal.html +1 -1
- data/doc/Compony/ModelFields/Email.html +1 -1
- data/doc/Compony/ModelFields/Float.html +1 -1
- data/doc/Compony/ModelFields/Integer.html +1 -1
- data/doc/Compony/ModelFields/Percentage.html +1 -1
- data/doc/Compony/ModelFields/Phone.html +1 -1
- data/doc/Compony/ModelFields/RichText.html +1 -1
- data/doc/Compony/ModelFields/String.html +1 -1
- data/doc/Compony/ModelFields/Text.html +1 -1
- data/doc/Compony/ModelFields/Time.html +1 -1
- data/doc/Compony/ModelFields/Url.html +1 -1
- data/doc/Compony/ModelFields.html +1 -1
- data/doc/Compony/ModelMixin.html +1 -1
- data/doc/Compony/NaturalOrdering.html +1 -1
- data/doc/Compony/RequestContext.html +1 -1
- data/doc/Compony/Version.html +1 -1
- data/doc/Compony/ViewHelpers.html +1 -1
- data/doc/Compony/VirtualModel.html +1 -1
- data/doc/Compony.html +1 -1
- data/doc/ComponyController.html +1 -1
- data/doc/_index.html +97 -1
- data/doc/file.CHANGELOG.html +758 -0
- data/doc/file.README.html +25 -4
- data/doc/file.basic_component.html +314 -0
- data/doc/file.cookbook.html +189 -0
- data/doc/file.destroy.html +105 -0
- data/doc/file.dsl_reference.html +672 -0
- data/doc/file.edit.html +109 -0
- data/doc/file.example.html +291 -0
- data/doc/file.example_advanced.html +257 -0
- data/doc/file.feasibility.html +115 -0
- data/doc/file.form.html +195 -0
- data/doc/file.generators.html +89 -0
- data/doc/file.glossary.html +217 -0
- data/doc/file.gotchas.html +222 -0
- data/doc/file.index.html +135 -0
- data/doc/file.inheritance.html +136 -0
- data/doc/file.installation.html +115 -0
- data/doc/file.integrations.html +218 -0
- data/doc/file.intents.html +265 -0
- data/doc/file.internal_datastructures.html +129 -0
- data/doc/file.list.html +253 -0
- data/doc/file.maintaining.html +127 -0
- data/doc/file.model_fields.html +137 -0
- data/doc/file.nesting.html +237 -0
- data/doc/file.new.html +109 -0
- data/doc/file.ownership.html +98 -0
- data/doc/file.patterns.html +669 -0
- data/doc/file.pre_built_components.html +99 -0
- data/doc/file.resourceful.html +181 -0
- data/doc/file.show.html +158 -0
- data/doc/file.standalone.html +233 -0
- data/doc/file.virtual_models.html +117 -0
- data/doc/file.with_form.html +157 -0
- data/doc/file_list.html +160 -0
- data/doc/guide/cookbook.md +41 -0
- data/doc/guide/dsl_reference.md +155 -0
- data/doc/guide/example_advanced.md +209 -0
- data/doc/guide/generators.md +1 -1
- data/doc/guide/glossary.md +42 -0
- data/doc/guide/gotchas.md +125 -0
- data/doc/guide/maintaining.md +64 -0
- data/doc/guide/patterns.md +681 -0
- data/doc/guide/pre_built_components/edit.md +1 -1
- data/doc/guide/pre_built_components/index.md +64 -1
- data/doc/guide/pre_built_components/list.md +111 -7
- data/doc/guide/pre_built_components/show.md +57 -2
- data/doc/guide/pre_built_components/with_form.md +56 -9
- data/doc/guide/pre_built_components.md +7 -2
- data/doc/guide/standalone.md +16 -1
- data/doc/index.html +25 -4
- data/doc/integrations.md +61 -0
- data/doc/llms.txt +62 -0
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/component.rb +8 -3
- data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +32 -15
- data/lib/compony/component_mixins/default/standalone/verb_dsl.rb +11 -3
- data/lib/compony/component_mixins/resourceful.rb +30 -16
- data/lib/compony/components/destroy.rb +21 -1
- data/lib/compony/components/edit.rb +25 -1
- data/lib/compony/components/form.rb +63 -21
- data/lib/compony/components/list.rb +1 -1
- data/lib/compony/components/new.rb +25 -1
- data/lib/compony/components/with_form.rb +20 -5
- data/lib/compony/intent.rb +1 -1
- metadata +43 -1
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>
|
|
7
|
+
File: gotchas
|
|
8
|
+
|
|
9
|
+
— Documentation by YARD 0.9.34
|
|
10
|
+
|
|
11
|
+
</title>
|
|
12
|
+
|
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
|
14
|
+
|
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
|
16
|
+
|
|
17
|
+
<script type="text/javascript">
|
|
18
|
+
pathId = "gotchas";
|
|
19
|
+
relpath = '';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
24
|
+
|
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="nav_wrap">
|
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
|
32
|
+
<div id="resizer"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div id="main" tabindex="-1">
|
|
36
|
+
<div id="header">
|
|
37
|
+
<div id="menu">
|
|
38
|
+
|
|
39
|
+
<a href="_index.html">Index</a> »
|
|
40
|
+
<span class="title">File: gotchas</span>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div id="search">
|
|
45
|
+
|
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
|
47
|
+
href="class_list.html">
|
|
48
|
+
|
|
49
|
+
<svg width="24" height="24">
|
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
|
53
|
+
</svg>
|
|
54
|
+
</a>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
<div class="clear"></div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div id="content"><div id='filecontents'>
|
|
61
|
+
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
|
+
|
|
63
|
+
<h1 id="label-Gotchas+-2F+anti-patterns">Gotchas / anti-patterns</h1>
|
|
64
|
+
|
|
65
|
+
<p>Known footguns, each with <strong>symptom → cause → fix</strong>. Skim before debugging.</p>
|
|
66
|
+
|
|
67
|
+
<h3 id="label-1.+standalone+without+an+explicit+path-3A">1. <code>standalone</code> without an explicit <code>path:</code></h3>
|
|
68
|
+
<ul><li>
|
|
69
|
+
<p><strong>Symptom:</strong> <code>undefined method '..._comp_path'</code>, or no route generated for the component.</p>
|
|
70
|
+
</li><li>
|
|
71
|
+
<p><strong>Cause:</strong> <code>standalone</code> only emits a route when a <code>path:</code> is given.</p>
|
|
72
|
+
</li><li>
|
|
73
|
+
<p><strong>Fix:</strong> Always pass <code>standalone path: 'users/show/:id' do ... end</code>. A component with no standalone is valid but must be nested in another component (has no URL).</p>
|
|
74
|
+
</li></ul>
|
|
75
|
+
|
|
76
|
+
<h3 id="label-2.+render_intent+-2F+render_sub_comp+output+not+appearing">2. <code>render_intent</code> / <code>render_sub_comp</code> output not appearing</h3>
|
|
77
|
+
<ul><li>
|
|
78
|
+
<p><strong>Symptom:</strong> The button/list silently missing from the rendered page.</p>
|
|
79
|
+
</li><li>
|
|
80
|
+
<p><strong>Cause:</strong> Dyny does not auto-print return values. <code>render_intent</code> returns an HTML string.</p>
|
|
81
|
+
</li><li>
|
|
82
|
+
<p><strong>Fix:</strong> Wrap it: <code>concat render_intent(:edit, user)</code> (Dyny’s equivalent of <code><%= %></code>).</p>
|
|
83
|
+
</li></ul>
|
|
84
|
+
|
|
85
|
+
<h3 id="label-3.+Overriding+respond+skips+authorization">3. Overriding <code>respond</code> skips authorization</h3>
|
|
86
|
+
<ul><li>
|
|
87
|
+
<p><strong>Symptom:</strong> An endpoint is reachable without the expected permission check.</p>
|
|
88
|
+
</li><li>
|
|
89
|
+
<p><strong>Cause:</strong> <code>authorize</code> is evaluated inside the <em>default</em> <code>respond</code>. A custom <code>respond</code> (especially the <code>nil</code>/all-formats one) replaces it.</p>
|
|
90
|
+
</li><li>
|
|
91
|
+
<p><strong>Fix:</strong> Re-check authorization yourself inside the custom <code>respond</code>, or keep a separate default <code>respond</code> for the relevant format.</p>
|
|
92
|
+
</li></ul>
|
|
93
|
+
|
|
94
|
+
<h3 id="label-4.+schema_field+with+the+foreign+key+name">4. <code>schema_field</code> with the foreign key name</h3>
|
|
95
|
+
<ul><li>
|
|
96
|
+
<p><strong>Symptom:</strong> Association param rejected by Schemacop / not assigned.</p>
|
|
97
|
+
</li><li>
|
|
98
|
+
<p><strong>Cause:</strong> Compony adds <code>_id</code> for associations automatically.</p>
|
|
99
|
+
</li><li>
|
|
100
|
+
<p><strong>Fix:</strong> Use the <strong>association name</strong>: <code>schema_field :author</code>, not <code>schema_field :author_id</code>. Same for <code>field :author</code> in <code>form_fields</code>.</p>
|
|
101
|
+
</li></ul>
|
|
102
|
+
|
|
103
|
+
<h3 id="label-5.+Model+without+label">5. Model without <code>label</code></h3>
|
|
104
|
+
<ul><li>
|
|
105
|
+
<p><strong>Symptom:</strong> Errors or blank text when Compony renders titles/links for the model.</p>
|
|
106
|
+
</li><li>
|
|
107
|
+
<p><strong>Cause:</strong> Compony calls <code>model.label</code> for display everywhere.</p>
|
|
108
|
+
</li><li>
|
|
109
|
+
<p><strong>Fix:</strong> Implement <code>def label</code> on every Compony model (or have a <code>label</code> column).</p>
|
|
110
|
+
</li></ul>
|
|
111
|
+
|
|
112
|
+
<h3 id="label-6.+Forgetting+to+forward+args+in+a+custom+initialize">6. Forgetting to forward args in a custom <code>initialize</code></h3>
|
|
113
|
+
<ul><li>
|
|
114
|
+
<p><strong>Symptom:</strong> <code>parent_comp</code>, <code>@data</code>, comp opts mysteriously <code>nil</code>; nesting broken.</p>
|
|
115
|
+
</li><li>
|
|
116
|
+
<p><strong>Cause:</strong> The base initializer wires essential state. Skipping <code>super</code> drops it.</p>
|
|
117
|
+
</li><li>
|
|
118
|
+
<p><strong>Fix:</strong> Call <code>super(*args, **kwargs, &block)</code> first, then set your own ivars. Prefer putting logic in <code>setup</code> instead of overriding <code>initialize</code>.</p>
|
|
119
|
+
</li></ul>
|
|
120
|
+
|
|
121
|
+
<h3 id="label-7.+Reading+a+label+without+its+block+argument">7. Reading a label without its block argument</h3>
|
|
122
|
+
<ul><li>
|
|
123
|
+
<p><strong>Symptom:</strong> <code>wrong number of arguments</code> from a label block.</p>
|
|
124
|
+
</li><li>
|
|
125
|
+
<p><strong>Cause:</strong> Resourceful components’ label blocks take the model; non-resourceful take none.</p>
|
|
126
|
+
</li><li>
|
|
127
|
+
<p><strong>Fix:</strong> <code>label(User.first)</code> for resourceful; <code>label</code> (no arg) otherwise. At most one arg.</p>
|
|
128
|
+
</li></ul>
|
|
129
|
+
|
|
130
|
+
<h3 id="label-8.+content+-3Aname+inside+a+block+tries+to+render+another+component-27s+block">8. <code>content :name</code> inside a block tries to render another component’s block</h3>
|
|
131
|
+
<ul><li>
|
|
132
|
+
<p><strong>Symptom:</strong> Content block not found / unexpected output.</p>
|
|
133
|
+
</li><li>
|
|
134
|
+
<p><strong>Cause:</strong> Nested <code>content :name</code> only renders a block defined in the <strong>same</strong> component.</p>
|
|
135
|
+
</li><li>
|
|
136
|
+
<p><strong>Fix:</strong> To embed another component use <code>render_sub_comp</code>, not nested <code>content</code>.</p>
|
|
137
|
+
</li></ul>
|
|
138
|
+
|
|
139
|
+
<h3 id="label-9.+Multiple+pages+in+one+component">9. Multiple pages in one component</h3>
|
|
140
|
+
<ul><li>
|
|
141
|
+
<p><strong>Symptom:</strong> Tangled <code>standalone</code>/<code>verb</code>/<code>respond</code> tree, confusing routes.</p>
|
|
142
|
+
</li><li>
|
|
143
|
+
<p><strong>Cause:</strong> Extra <code>standalone</code> calls are for <em>companion</em> endpoints (AJAX tiles, autocomplete JSON) of the <em>same</em> screen — not for separate pages.</p>
|
|
144
|
+
</li><li>
|
|
145
|
+
<p><strong>Fix:</strong> One screen = one component exposing one main route. Make another component for another page.</p>
|
|
146
|
+
</li></ul>
|
|
147
|
+
|
|
148
|
+
<h3 id="label-10.+Resourceful+component+on+a+path+without+-3Aid">10. Resourceful component on a path without <code>:id</code></h3>
|
|
149
|
+
<ul><li>
|
|
150
|
+
<p><strong>Symptom:</strong> <code>Couldn't find <Model> without an ID</code> (e.g. an Index at <code>/users</code>).</p>
|
|
151
|
+
</li><li>
|
|
152
|
+
<p><strong>Cause:</strong> Default <code>load_data</code> does <code>data_class.find(params[:id])</code>.</p>
|
|
153
|
+
</li><li>
|
|
154
|
+
<p><strong>Fix:</strong> Override <code>load_data { @data = User.all }</code> (or your scope) for collection/index components.</p>
|
|
155
|
+
</li></ul>
|
|
156
|
+
|
|
157
|
+
<h3 id="label-11.+redirect_to+with+a+hardcoded+path">11. <code>redirect_to</code> with a hardcoded path</h3>
|
|
158
|
+
<ul><li>
|
|
159
|
+
<p><strong>Symptom:</strong> Links break after renaming/moving a component.</p>
|
|
160
|
+
</li><li>
|
|
161
|
+
<p><strong>Cause:</strong> Bypassing the intent system.</p>
|
|
162
|
+
</li><li>
|
|
163
|
+
<p><strong>Fix:</strong> Use <code>redirect_to Compony.path(:index, :users)</code> / <code>Compony.path(:show, @data)</code>.</p>
|
|
164
|
+
</li></ul>
|
|
165
|
+
|
|
166
|
+
<h3 id="label-12.+ActiveStorage+attachment+on+a+virtual+model">12. ActiveStorage attachment on a virtual model</h3>
|
|
167
|
+
<ul><li>
|
|
168
|
+
<p><strong>Symptom:</strong> Uploaded file not persisted for a <code>Compony::VirtualModel</code>.</p>
|
|
169
|
+
</li><li>
|
|
170
|
+
<p><strong>Cause:</strong> Virtual models aren’t backed by a real table; the default <code>store_data</code> save doesn’t persist attachments.</p>
|
|
171
|
+
</li><li>
|
|
172
|
+
<p><strong>Fix:</strong> Override <code>store_data</code> to only validate (<code>@create_succeeded = @data.validate</code>) and perform the real mutation/attachment in <code>on_created_respond</code>. See <a href="/doc/guide/virtual_models_md.html">virtual_models.md</a>.</p>
|
|
173
|
+
</li></ul>
|
|
174
|
+
|
|
175
|
+
<h3 id="label-13.+tailwindcss-rails+purges+Compony+styles">13. <code>tailwindcss-rails</code> purges Compony styles</h3>
|
|
176
|
+
<ul><li>
|
|
177
|
+
<p><strong>Symptom:</strong> Compony component markup unstyled in production.</p>
|
|
178
|
+
</li><li>
|
|
179
|
+
<p><strong>Cause:</strong> Tailwind’s unused-CSS purge doesn’t scan component classes (their HTML isn’t in <code>app/views</code>).</p>
|
|
180
|
+
</li><li>
|
|
181
|
+
<p><strong>Fix:</strong> Safelist the classes, or don’t use <code>tailwindcss-rails</code> with Compony (see README “Caveats”).</p>
|
|
182
|
+
</li></ul>
|
|
183
|
+
|
|
184
|
+
<h3 id="label-14.+Public+endpoint+still+401-2Fredirecting">14. Public endpoint still 401/redirecting</h3>
|
|
185
|
+
<ul><li>
|
|
186
|
+
<p><strong>Symptom:</strong> Webhook/public action blocked by app auth or CSRF.</p>
|
|
187
|
+
</li><li>
|
|
188
|
+
<p><strong>Cause:</strong> <code>skip_authentication!</code> alone doesn’t remove CSRF, and <code>authorize</code> is still mandatory.</p>
|
|
189
|
+
</li><li>
|
|
190
|
+
<p><strong>Fix:</strong> In the standalone: <code>skip_authentication!</code> + <code>skip_forgery_protection!</code>, and in the verb <code>authorize { true }</code> (then validate a bearer token yourself).</p>
|
|
191
|
+
</li></ul>
|
|
192
|
+
|
|
193
|
+
<h3 id="label-15.+Hand-rolled+endpoint+where+a+pre-built+CRUD+component+exists">15. Hand-rolled endpoint where a pre-built CRUD component exists</h3>
|
|
194
|
+
<ul><li>
|
|
195
|
+
<p><strong>Symptom:</strong> A custom <code>Compony::Component</code> with manual <code>button_to</code>/standalone for delete/edit/create, duplicating routing, authorization, confirmation UI, styling.</p>
|
|
196
|
+
</li><li>
|
|
197
|
+
<p><strong>Cause:</strong> Reaching for a bespoke component instead of the pre-built one.</p>
|
|
198
|
+
</li><li>
|
|
199
|
+
<p><strong>Fix:</strong> For CRUD use the pre-built parents (<code>Destroy</code>/<code>Edit</code>/<code>New</code>/<code>Show</code>/<code>Index</code>) and point with <code>render_intent(:destroy, record)</code>. Reserve custom <code>Compony::Component</code> standalones for genuinely non-CRUD actions (job dispatch, webhooks, multi-record ops). Put a resourceful component in the family of the model it operates on, not the family it is navigated from; pass parent context via path params.</p>
|
|
200
|
+
</li></ul>
|
|
201
|
+
|
|
202
|
+
<h3 id="label-16.+attr_accessor+on+a+model+for+form-only+fields">16. <code>attr_accessor</code> on a model for form-only fields</h3>
|
|
203
|
+
<ul><li>
|
|
204
|
+
<p><strong>Symptom:</strong> Virtual form fields declared as <code>attr_accessor</code> on the ActiveRecord model.</p>
|
|
205
|
+
</li><li>
|
|
206
|
+
<p><strong>Cause:</strong> Polluting the persistent model with form-only concerns.</p>
|
|
207
|
+
</li><li>
|
|
208
|
+
<p><strong>Fix:</strong> Use an <code>ActiveType::Record[Model]</code> (or <code>Compony::VirtualModel</code>) inner class on the component with <code>ar_attribute</code> + <code>field</code>, and set <code>data_class</code> to it. See <a href="/doc/guide/virtual_models_md.html">virtual_models.md</a>.</p>
|
|
209
|
+
</li></ul>
|
|
210
|
+
|
|
211
|
+
<p><a href="/README_md.html#guide--documentation">Guide index</a></p>
|
|
212
|
+
</div></div>
|
|
213
|
+
|
|
214
|
+
<div id="footer">
|
|
215
|
+
Generated on Mon May 18 13:55:34 2026 by
|
|
216
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
217
|
+
0.9.34 (ruby-3.3.5).
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
</div>
|
|
221
|
+
</body>
|
|
222
|
+
</html>
|
data/doc/file.index.html
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>
|
|
7
|
+
File: index
|
|
8
|
+
|
|
9
|
+
— Documentation by YARD 0.9.34
|
|
10
|
+
|
|
11
|
+
</title>
|
|
12
|
+
|
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
|
14
|
+
|
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
|
16
|
+
|
|
17
|
+
<script type="text/javascript">
|
|
18
|
+
pathId = "index";
|
|
19
|
+
relpath = '';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
24
|
+
|
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="nav_wrap">
|
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
|
32
|
+
<div id="resizer"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div id="main" tabindex="-1">
|
|
36
|
+
<div id="header">
|
|
37
|
+
<div id="menu">
|
|
38
|
+
|
|
39
|
+
<a href="_index.html">Index</a> »
|
|
40
|
+
<span class="title">File: index</span>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div id="search">
|
|
45
|
+
|
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
|
47
|
+
href="class_list.html">
|
|
48
|
+
|
|
49
|
+
<svg width="24" height="24">
|
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
|
53
|
+
</svg>
|
|
54
|
+
</a>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
<div class="clear"></div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div id="content"><div id='filecontents'><ul><li>
|
|
61
|
+
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
|
+
</li><li>
|
|
63
|
+
<p><a href="/doc/guide/pre_built_components_md.html">List of pre-built components</a></p>
|
|
64
|
+
</li></ul>
|
|
65
|
+
|
|
66
|
+
<h1 id="label-Pre-built+components-3A+Index">Pre-built components: Index</h1>
|
|
67
|
+
|
|
68
|
+
<p><code>Compony::Components::Index</code> is a resourceful standalone component corresponding to Rails’ <code>index</code> controller action. It holds a collection of records and is a thin wrapper that nests the href="./list_md.html"></a> component of the same family.</p>
|
|
69
|
+
|
|
70
|
+
<h2 id="label-What+it+does+by+default">What it does by default</h2>
|
|
71
|
+
|
|
72
|
+
<p>The shipped <code>setup</code> (see <code>lib/compony/components/index.rb</code>) is deliberately minimal:</p>
|
|
73
|
+
<ul><li>
|
|
74
|
+
<p><strong>Route:</strong> <code>standalone path: family_name</code> with a <code>verb :get</code> authorized by <code>can?(:index, data_class)</code>, e.g. <code>/users</code>.</p>
|
|
75
|
+
</li><li>
|
|
76
|
+
<p><strong>Label:</strong> <code>label(:all) { data_class.model_name.human(count: 2) }</code> — e.g. “Users”.</p>
|
|
77
|
+
</li><li>
|
|
78
|
+
<p><strong>Data:</strong> <code>load_data { @data = data_class.accessible_by(controller.current_ability) }</code> — the full CanCanCan[https://github.com/CanCanCommunity/cancancan]-scoped collection.</p>
|
|
79
|
+
</li><li>
|
|
80
|
+
<p><strong>Exposed intent:</strong> adds a <code>:new</code> intent (unless the model is <a href="/doc/guide/ownership_md.html">owned</a> by another).</p>
|
|
81
|
+
</li><li>
|
|
82
|
+
<p><strong>Content:</strong> <code>concat render_sub_comp(:list, @data)</code> — delegates all rendering to the family’s <code>List</code>.</p>
|
|
83
|
+
</li></ul>
|
|
84
|
+
|
|
85
|
+
<p>So with both an <code>Index</code> and a <code>List</code> component present, a family lists out of the box:</p>
|
|
86
|
+
|
|
87
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'><span class='object_link'><a href="Components.html" title="Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'>Users</span><span class='op'>::</span><span class='const'>Index</span> <span class='op'><</span> <span class='const'><span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components.html" title="Compony::Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components/Index.html" title="Compony::Components::Index (class)">Index</a></span></span><span class='semicolon'>;</span> <span class='kw'>end</span>
|
|
88
|
+
<span class='kw'>class</span> <span class='const'><span class='object_link'><a href="Components.html" title="Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'>Users</span><span class='op'>::</span><span class='const'>List</span> <span class='op'><</span> <span class='const'><span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components.html" title="Compony::Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components/List.html" title="Compony::Components::List (class)">List</a></span></span>
|
|
89
|
+
<span class='id identifier rubyid_setup'>setup</span> <span class='lbrace'>{</span> <span class='id identifier rubyid_columns'>columns</span> <span class='symbol'>:name</span><span class='comma'>,</span> <span class='symbol'>:email</span> <span class='rbrace'>}</span>
|
|
90
|
+
<span class='kw'>end</span>
|
|
91
|
+
</code></pre>
|
|
92
|
+
|
|
93
|
+
<h2 id="label-Typical+overrides">Typical overrides</h2>
|
|
94
|
+
|
|
95
|
+
<p>Narrow or order the collection:</p>
|
|
96
|
+
|
|
97
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'><span class='object_link'><a href="Components.html" title="Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'>Users</span><span class='op'>::</span><span class='const'>Index</span> <span class='op'><</span> <span class='const'><span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components.html" title="Compony::Components (module)">Components</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/Components/Index.html" title="Compony::Components::Index (class)">Index</a></span></span>
|
|
98
|
+
<span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
99
|
+
<span class='id identifier rubyid_load_data'>load_data</span> <span class='lbrace'>{</span> <span class='ivar'>@data</span> <span class='op'>=</span> <span class='const'>User</span><span class='period'>.</span><span class='id identifier rubyid_accessible_by'>accessible_by</span><span class='lparen'>(</span><span class='id identifier rubyid_current_ability'>current_ability</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_active'>active</span><span class='period'>.</span><span class='id identifier rubyid_order'>order</span><span class='lparen'>(</span><span class='symbol'>:name</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
|
|
100
|
+
<span class='kw'>end</span>
|
|
101
|
+
<span class='kw'>end</span>
|
|
102
|
+
</code></pre>
|
|
103
|
+
|
|
104
|
+
<p>Customize the action toolbar via <a href="/doc/guide/intents_md.html#exposed-intents">exposed intents</a>:</p>
|
|
105
|
+
|
|
106
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
107
|
+
<span class='id identifier rubyid_exposed_intents'>exposed_intents</span> <span class='kw'>do</span>
|
|
108
|
+
<span class='id identifier rubyid_add'>add</span> <span class='symbol'>:index</span><span class='comma'>,</span> <span class='symbol'>:users</span><span class='comma'>,</span> <span class='label'>label:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>CSV</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>name:</span> <span class='symbol'>:csv</span><span class='comma'>,</span> <span class='label'>path:</span> <span class='lbrace'>{</span> <span class='label'>format:</span> <span class='symbol'>:csv</span> <span class='rbrace'>}</span>
|
|
109
|
+
<span class='id identifier rubyid_add'>add</span> <span class='symbol'>:import</span><span class='comma'>,</span> <span class='symbol'>:users</span><span class='comma'>,</span> <span class='label'>method:</span> <span class='symbol'>:post</span><span class='comma'>,</span> <span class='label'>before:</span> <span class='symbol'>:new</span>
|
|
110
|
+
<span class='kw'>end</span>
|
|
111
|
+
<span class='kw'>end</span>
|
|
112
|
+
</code></pre>
|
|
113
|
+
|
|
114
|
+
<p>Add a second standalone route serving an alternative <code>List</code>:</p>
|
|
115
|
+
|
|
116
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
117
|
+
<span class='id identifier rubyid_standalone'>standalone</span> <span class='label'>path:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>users/archived</span><span class='tstring_end'>'</span></span>
|
|
118
|
+
<span class='id identifier rubyid_content'>content</span> <span class='symbol'>:main</span><span class='comma'>,</span> <span class='label'>hidden:</span> <span class='kw'>true</span> <span class='kw'>do</span>
|
|
119
|
+
<span class='id identifier rubyid_concat'>concat</span> <span class='id identifier rubyid_render_sub_comp'>render_sub_comp</span><span class='lparen'>(</span><span class='symbol'>:list</span><span class='comma'>,</span> <span class='ivar'>@data</span><span class='period'>.</span><span class='id identifier rubyid_archived'>archived</span><span class='rparen'>)</span>
|
|
120
|
+
<span class='kw'>end</span>
|
|
121
|
+
<span class='kw'>end</span>
|
|
122
|
+
</code></pre>
|
|
123
|
+
|
|
124
|
+
<p>In practice apps put the layout/markup chrome in a <code>BaseComponents::Index</code> and inherit from that — see <a href="../patterns_md.html#3-index--load_data-scope--nested-list">Real-world patterns</a>. For column/filter/sort configuration, see href="./list_md.html"></a>.</p>
|
|
125
|
+
</div></div>
|
|
126
|
+
|
|
127
|
+
<div id="footer">
|
|
128
|
+
Generated on Mon May 18 13:55:33 2026 by
|
|
129
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
130
|
+
0.9.34 (ruby-3.3.5).
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
</div>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>
|
|
7
|
+
File: inheritance
|
|
8
|
+
|
|
9
|
+
— Documentation by YARD 0.9.34
|
|
10
|
+
|
|
11
|
+
</title>
|
|
12
|
+
|
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
|
14
|
+
|
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
|
16
|
+
|
|
17
|
+
<script type="text/javascript">
|
|
18
|
+
pathId = "inheritance";
|
|
19
|
+
relpath = '';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
24
|
+
|
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="nav_wrap">
|
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
|
32
|
+
<div id="resizer"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div id="main" tabindex="-1">
|
|
36
|
+
<div id="header">
|
|
37
|
+
<div id="menu">
|
|
38
|
+
|
|
39
|
+
<a href="_index.html">Index</a> »
|
|
40
|
+
<span class="title">File: inheritance</span>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div id="search">
|
|
45
|
+
|
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
|
47
|
+
href="class_list.html">
|
|
48
|
+
|
|
49
|
+
<svg width="24" height="24">
|
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
|
53
|
+
</svg>
|
|
54
|
+
</a>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
<div class="clear"></div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div id="content"><div id='filecontents'>
|
|
61
|
+
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
|
+
|
|
63
|
+
<h1 id="label-Inheritance">Inheritance</h1>
|
|
64
|
+
|
|
65
|
+
<p>Compony’s key advantage is that you can write DRYer code with it. To achieve this, you are encouraged to create abstract components, implement common functionality there and inherit from them in other components.</p>
|
|
66
|
+
|
|
67
|
+
<p>Examples:</p>
|
|
68
|
+
<ul><li>
|
|
69
|
+
<p>Perhaps you have code shared in all of your <code>New</code> components. In this case, create <code>BaseComponents::New</code> and inherit from <code>Compony::Components::New</code>. In <code>setup</code> of your base component, you can now perform all the configurations needed. Now you may inherit from it: <code>class Components::Users::New < BaseComponents::New</code>.</p>
|
|
70
|
+
</li><li>
|
|
71
|
+
<p>Perhaps you often implement the same kind of component, for instance an index component displaying a filterable list. In this case, create <code>BaseComponents::Index</code> and inherit as follows: <code>class Components::Users::Index < BaseComponents::Index</code>.</p>
|
|
72
|
+
</li></ul>
|
|
73
|
+
|
|
74
|
+
<h2 id="label-Behavior">Behavior</h2>
|
|
75
|
+
|
|
76
|
+
<p>When inheriting from another component class, <code>setup</code> can be called in the child as well in order to overwrite specified configurations. The parent’s <code>setup</code> block will be run first, then the child’s, then the grand-child’s and so on.</p>
|
|
77
|
+
|
|
78
|
+
<p>Omit any configuration that you want to keep from the parent class. For instance, if your parent’s setup looks like this:</p>
|
|
79
|
+
|
|
80
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
81
|
+
<span class='id identifier rubyid_standalone'>standalone</span> <span class='label'>path:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>foo/bar</span><span class='tstring_end'>'</span></span> <span class='kw'>do</span>
|
|
82
|
+
<span class='id identifier rubyid_layout'>layout</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>funky</span><span class='tstring_end'>'</span></span>
|
|
83
|
+
<span class='id identifier rubyid_verb'>verb</span> <span class='symbol'>:get</span> <span class='kw'>do</span>
|
|
84
|
+
<span class='id identifier rubyid_authorize'>authorize</span> <span class='lbrace'>{</span> <span class='kw'>true</span> <span class='rbrace'>}</span>
|
|
85
|
+
<span class='kw'>end</span>
|
|
86
|
+
<span class='kw'>end</span>
|
|
87
|
+
<span class='id identifier rubyid_content'>content</span> <span class='kw'>do</span>
|
|
88
|
+
<span class='id identifier rubyid_h1'>h1</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Test</span><span class='tstring_end'>'</span></span>
|
|
89
|
+
<span class='kw'>end</span>
|
|
90
|
+
<span class='kw'>end</span>
|
|
91
|
+
</code></pre>
|
|
92
|
+
|
|
93
|
+
<p>Assuming you want to implement a child class that only differs by layout and adds more content below “test”, you can implement:</p>
|
|
94
|
+
|
|
95
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
96
|
+
<span class='id identifier rubyid_standalone'>standalone</span> <span class='kw'>do</span>
|
|
97
|
+
<span class='id identifier rubyid_layout'>layout</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>dark</span><span class='tstring_end'>'</span></span>
|
|
98
|
+
<span class='kw'>end</span>
|
|
99
|
+
<span class='id identifier rubyid_content'>content</span> <span class='symbol'>:below</span> <span class='kw'>do</span>
|
|
100
|
+
<span class='id identifier rubyid_para'>para</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>This will appear below "Test".</span><span class='tstring_end'>'</span></span>
|
|
101
|
+
<span class='kw'>end</span>
|
|
102
|
+
<span class='kw'>end</span>
|
|
103
|
+
</code></pre>
|
|
104
|
+
|
|
105
|
+
<h2 id="label-Un-exposing+a+component">Un-exposing a component</h2>
|
|
106
|
+
|
|
107
|
+
<p>If a component’s parent class is <a href="./standalone_md.html">standalone</a> but the child should not be, use <code>clear_standalone!</code>:</p>
|
|
108
|
+
|
|
109
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
|
|
110
|
+
<span class='id identifier rubyid_clear_standalone!'>clear_standalone!</span>
|
|
111
|
+
<span class='kw'>end</span>
|
|
112
|
+
</code></pre>
|
|
113
|
+
|
|
114
|
+
<h2 id="label-Best+practice">Best practice</h2>
|
|
115
|
+
|
|
116
|
+
<p>Compony has the following convention:</p>
|
|
117
|
+
<ul><li>
|
|
118
|
+
<p>implement a custom base component in the directory <code>app/compony/base_components/your_component.rb</code></p>
|
|
119
|
+
</li><li>
|
|
120
|
+
<p>name the class <code>BaseComponents::YourComponent</code> where <code>BaseComponents</code> is typically a module simple meant for namespacing</p>
|
|
121
|
+
</li></ul>
|
|
122
|
+
|
|
123
|
+
<p>When respecting these conventions, Compony’s <a href="/doc/guide/generators_md.html">generators</a> will automatically make generated classes inherit from the suitable base component if one is available. In the example above, <code>rails g component Users::Index</code> will automatically make the generated class inherit from <code>BaseComponent::Index</code>.</p>
|
|
124
|
+
|
|
125
|
+
<p><a href="/README_md.html#guide--documentation">Guide index</a></p>
|
|
126
|
+
</div></div>
|
|
127
|
+
|
|
128
|
+
<div id="footer">
|
|
129
|
+
Generated on Mon May 18 13:55:33 2026 by
|
|
130
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
131
|
+
0.9.34 (ruby-3.3.5).
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
</div>
|
|
135
|
+
</body>
|
|
136
|
+
</html>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>
|
|
7
|
+
File: installation
|
|
8
|
+
|
|
9
|
+
— Documentation by YARD 0.9.34
|
|
10
|
+
|
|
11
|
+
</title>
|
|
12
|
+
|
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
|
14
|
+
|
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
|
16
|
+
|
|
17
|
+
<script type="text/javascript">
|
|
18
|
+
pathId = "installation";
|
|
19
|
+
relpath = '';
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
24
|
+
|
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="nav_wrap">
|
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
|
32
|
+
<div id="resizer"></div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div id="main" tabindex="-1">
|
|
36
|
+
<div id="header">
|
|
37
|
+
<div id="menu">
|
|
38
|
+
|
|
39
|
+
<a href="_index.html">Index</a> »
|
|
40
|
+
<span class="title">File: installation</span>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div id="search">
|
|
45
|
+
|
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
|
47
|
+
href="class_list.html">
|
|
48
|
+
|
|
49
|
+
<svg width="24" height="24">
|
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
|
53
|
+
</svg>
|
|
54
|
+
</a>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
<div class="clear"></div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div id="content"><div id='filecontents'>
|
|
61
|
+
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
|
+
|
|
63
|
+
<h1 id="label-Installation">Installation</h1>
|
|
64
|
+
|
|
65
|
+
<h2 id="label-Installing+Compony">Installing Compony</h2>
|
|
66
|
+
|
|
67
|
+
<p>First, add Compony to your Gemfile:</p>
|
|
68
|
+
|
|
69
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gem'>gem</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>compony</span><span class='tstring_end'>'</span></span>
|
|
70
|
+
</code></pre>
|
|
71
|
+
|
|
72
|
+
<p>Then run <code>bundle install</code>.</p>
|
|
73
|
+
|
|
74
|
+
<p>Create the directory <code>app/components</code>.</p>
|
|
75
|
+
|
|
76
|
+
<p>In <code>app/models/application_record.rb</code>, add the following line below <code>primary_abstract_class</code>:</p>
|
|
77
|
+
|
|
78
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/ModelMixin.html" title="Compony::ModelMixin (module)">ModelMixin</a></span></span>
|
|
79
|
+
</code></pre>
|
|
80
|
+
|
|
81
|
+
<h2 id="label-Installing+CanCanCan">Installing CanCanCan</h2>
|
|
82
|
+
|
|
83
|
+
<p>Create the file <code>app/models/ability.rb</code> with the following content:</p>
|
|
84
|
+
|
|
85
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>Ability</span>
|
|
86
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'>CanCan</span><span class='op'>::</span><span class='const'>Ability</span>
|
|
87
|
+
|
|
88
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span><span class='lparen'>(</span><span class='id identifier rubyid__user'>_user</span><span class='rparen'>)</span>
|
|
89
|
+
<span class='id identifier rubyid_can'>can</span> <span class='symbol'>:manage</span><span class='comma'>,</span> <span class='symbol'>:all</span>
|
|
90
|
+
<span class='kw'>end</span>
|
|
91
|
+
<span class='kw'>end</span>
|
|
92
|
+
</code></pre>
|
|
93
|
+
|
|
94
|
+
<p>This is an initial dummy ability that allows anyone to do anything. Most likely, you will want to adjust the file. For documentation, refer to <a href="https://github.com/CanCanCommunity/cancancan/">github.com/CanCanCommunity/cancancan/</a>.</p>
|
|
95
|
+
|
|
96
|
+
<h2 id="label-Optional-3A+installing+anchormodel">Optional: installing anchormodel</h2>
|
|
97
|
+
|
|
98
|
+
<p>To take advantage of the anchormodel integration, follow the installation instructions under <a href="https://github.com/kalsan/anchormodel/">github.com/kalsan/anchormodel/</a>.</p>
|
|
99
|
+
|
|
100
|
+
<h2 id="label-Optional-3A+installing+active_type">Optional: installing <code>active_type</code></h2>
|
|
101
|
+
|
|
102
|
+
<p>To take advantage of <a href="./virtual_models_md.html">virtual models</a> through the <code>active_type</code> integration, follow the instructions under <a href="https://github.com/makandra/active_type">github.com/makandra/active_type</a></p>
|
|
103
|
+
|
|
104
|
+
<p><a href="/README_md.html#guide--documentation">Guide index</a></p>
|
|
105
|
+
</div></div>
|
|
106
|
+
|
|
107
|
+
<div id="footer">
|
|
108
|
+
Generated on Mon May 18 13:55:32 2026 by
|
|
109
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
110
|
+
0.9.34 (ruby-3.3.5).
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
</div>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|