compony 0.11.11 → 0.11.13
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/.rspec +2 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +145 -106
- data/README.md +12 -1
- data/Rakefile +10 -0
- data/TODO.md +2 -1
- data/VERSION +1 -1
- data/compony.gemspec +5 -3
- data/config/locales/es.yml +46 -0
- data/doc/ComponentGenerator.html +1 -1
- data/doc/Components.html +1 -1
- data/doc/ComponentsGenerator.html +1 -1
- data/doc/Compony/Component.html +1 -1
- 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 +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +1 -1
- data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
- data/doc/Compony/ComponentMixins/Default.html +1 -1
- data/doc/Compony/ComponentMixins/Resourceful.html +1 -1
- 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 +1 -1
- data/doc/Compony/Components/Edit.html +1 -1
- data/doc/Compony/Components/Form.html +1 -1
- data/doc/Compony/Components/Index.html +1 -1
- data/doc/Compony/Components/List.html +1 -1
- data/doc/Compony/Components/New.html +1 -1
- data/doc/Compony/Components/Show.html +1 -1
- data/doc/Compony/Components/WithForm.html +1 -1
- 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 +1 -1
- data/doc/Compony/ManageIntentsDsl.html +2 -2
- 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 +8 -2
- 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 +1 -1
- data/doc/file.CHANGELOG.html +88 -76
- data/doc/file.README.html +21 -11
- data/doc/file.basic_component.html +14 -14
- data/doc/file.cookbook.html +27 -27
- data/doc/file.destroy.html +2 -2
- data/doc/file.dsl_reference.html +199 -199
- data/doc/file.edit.html +3 -3
- data/doc/file.example.html +13 -13
- data/doc/file.example_advanced.html +10 -10
- data/doc/file.feasibility.html +2 -2
- data/doc/file.form.html +7 -7
- data/doc/file.generators.html +3 -3
- data/doc/file.glossary.html +44 -44
- data/doc/file.gotchas.html +35 -35
- data/doc/file.index.html +10 -10
- data/doc/file.inheritance.html +5 -5
- data/doc/file.installation.html +9 -9
- data/doc/file.integrations.html +46 -46
- data/doc/file.intents.html +11 -11
- data/doc/file.internal_datastructures.html +6 -6
- data/doc/file.list.html +35 -35
- data/doc/file.maintaining.html +21 -21
- data/doc/file.model_fields.html +3 -3
- data/doc/file.nesting.html +5 -5
- data/doc/file.new.html +3 -3
- data/doc/file.ownership.html +2 -2
- data/doc/file.patterns.html +50 -50
- data/doc/file.pre_built_components.html +2 -2
- data/doc/file.resourceful.html +5 -5
- data/doc/file.show.html +17 -17
- data/doc/file.standalone.html +12 -12
- data/doc/file.virtual_models.html +2 -2
- data/doc/file.with_form.html +23 -23
- data/doc/index.html +21 -11
- data/doc/top-level-namespace.html +1 -1
- data/lib/compony/model_fields/base.rb +3 -0
- data/spec/README.md +22 -0
- data/spec/compony/component_spec.rb +80 -0
- data/spec/compony/compony_spec.rb +102 -0
- data/spec/compony/intent_spec.rb +94 -0
- data/spec/compony/method_accessible_hash_spec.rb +32 -0
- data/spec/compony/model_fields_spec.rb +70 -0
- data/spec/compony/model_mixin_spec.rb +81 -0
- data/spec/compony/natural_ordering_spec.rb +61 -0
- data/spec/dummy/app/components/statics/home.rb +17 -0
- data/spec/dummy/app/components/statics/secret.rb +15 -0
- data/spec/dummy/app/components/users/destroy.rb +2 -0
- data/spec/dummy/app/components/users/edit.rb +2 -0
- data/spec/dummy/app/components/users/form.rb +14 -0
- data/spec/dummy/app/components/users/index.rb +29 -0
- data/spec/dummy/app/components/users/new.rb +2 -0
- data/spec/dummy/app/components/users/show.rb +26 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/models/ability.rb +7 -0
- data/spec/dummy/app/models/application_record.rb +4 -0
- data/spec/dummy/app/models/user.rb +22 -0
- data/spec/dummy/app/views/layouts/application.html.erb +7 -0
- data/spec/dummy/config/application.rb +20 -0
- data/spec/dummy/config/database.yml +3 -0
- data/spec/dummy/config/environment.rb +3 -0
- data/spec/dummy/config/initializers/simple_form.rb +9 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/schema.rb +14 -0
- data/spec/rails_helper.rb +23 -0
- data/spec/requests/authorization_spec.rb +16 -0
- data/spec/requests/plain_component_spec.rb +9 -0
- data/spec/requests/routing_spec.rb +20 -0
- data/spec/requests/users_crud_spec.rb +99 -0
- metadata +63 -1
data/doc/file.edit.html
CHANGED
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
<p><a href="/doc/guide/pre_built_components_md.html">List of pre-built components</a></p>
|
|
64
64
|
</li></ul>
|
|
65
65
|
|
|
66
|
-
<h1 id="
|
|
66
|
+
<h1 id="pre-built-components-edit">Pre-built components: Edit</h1>
|
|
67
67
|
|
|
68
68
|
<p>This component is the Compony equivalent to a typical Rails controller’s <code>edit</code> and <code>update</code> actions.</p>
|
|
69
69
|
|
|
70
|
-
<p><code>Compony::Components::Edit</code> is a resourceful standalone component based on href="./with_form_md.html"></a> that listens to two verbs:</p>
|
|
70
|
+
<p><code>Compony::Components::Edit</code> is a resourceful standalone component based on <a href="./with_form_md.html"><code>WithForm</code></a> that listens to two verbs:</p>
|
|
71
71
|
<ul><li>
|
|
72
72
|
<p>GET will cause the Edit component to load a record given by ID and render the form based on that record. If the record does not exist, a HTTP 404 code is returned.</p>
|
|
73
73
|
</li><li>
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
</div></div>
|
|
100
100
|
|
|
101
101
|
<div id="footer">
|
|
102
|
-
Generated on
|
|
102
|
+
Generated on Tue Aug 18 14:36:34 2026 by
|
|
103
103
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
104
104
|
0.9.34 (ruby-3.4.9).
|
|
105
105
|
</div>
|
data/doc/file.example.html
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<div id="content"><div id='filecontents'>
|
|
61
61
|
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
62
|
|
|
63
|
-
<h1 id="
|
|
63
|
+
<h1 id="example">Example</h1>
|
|
64
64
|
|
|
65
65
|
<p>To get you a rough idea what working with Compony feels like, let’s look at a small dummy application using Compony from scratch, to make this example as explicit as possible. In practice, much of the logic shown here would be moved to abstract components that you can inherit from.</p>
|
|
66
66
|
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
|
|
71
71
|
<p>Let’s implement a simple user management page with Compony. User’s have a name, an integer age, a comment, as well as a role (which we will conveniently model using <code>AnchorModel</code>: <a href="https://github.com/kalsan/anchormodel">github.com/kalsan/anchormodel</a>). We want to be able to list, show, create, edit and destroy users. Users having the role Admin shall not be destroyed.</p>
|
|
72
72
|
|
|
73
|
-
<h2 id="
|
|
73
|
+
<h2 id="the-user-model">The User model</h2>
|
|
74
74
|
|
|
75
75
|
<p>We’ll assume a model that has the standard Rails schema:</p>
|
|
76
76
|
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
<span class='kw'>end</span>
|
|
109
109
|
</code></pre>
|
|
110
110
|
|
|
111
|
-
<h2 id="
|
|
111
|
+
<h2 id="the-show-component">The Show component</h2>
|
|
112
112
|
|
|
113
113
|
<p>This components loads a user by reading the param <code>id</code>. It then displays a simple table showing all the fields defined above.</p>
|
|
114
114
|
|
|
@@ -164,11 +164,11 @@
|
|
|
164
164
|
|
|
165
165
|
<p>Here is what our Show component looks like when we have a layout with the bare minimum and no styling at all:</p>
|
|
166
166
|
|
|
167
|
-
<p><img src="/doc/imgs/intro-example-show.png"
|
|
167
|
+
<p><img src="/doc/imgs/intro-example-show.png" alt="Screenshot"> of our component with an absolutely minimal layout</p>
|
|
168
168
|
|
|
169
169
|
<p>It is important to note that button styles, navigation, notifications etc. are handled by the application layout. In this and the subsequent screenshots, we explicitely use minimalism, as it makes the generated HTML clearer.</p>
|
|
170
170
|
|
|
171
|
-
<h2 id="
|
|
171
|
+
<h2 id="the-destroy-component">The Destroy component</h2>
|
|
172
172
|
|
|
173
173
|
<p>Compony has a built-in abstract <code>Destroy</code> component which displays a confirmation message and destroys the record if the verb is <code>DELETE</code>. This is a good example for how DRY code can become for “boring” components. Since everything is provided with an overridable default, components without special logic can actually be left blank:</p>
|
|
174
174
|
|
|
@@ -178,9 +178,9 @@
|
|
|
178
178
|
|
|
179
179
|
<p>Note that this component is fully functional. All is handled by the class it inherits from:</p>
|
|
180
180
|
|
|
181
|
-
<p><img src="/doc/imgs/intro-example-destroy.png"
|
|
181
|
+
<p><img src="/doc/imgs/intro-example-destroy.png" alt="Screenshot"> of the destroy component</p>
|
|
182
182
|
|
|
183
|
-
<h2 id="
|
|
183
|
+
<h2 id="the-new-component-and-the-form-component">The New component and the Form component</h2>
|
|
184
184
|
|
|
185
185
|
<p>Compony also has a pre-built abstract <code>New</code> component that handles routing and resource manipulation. It combines the controller actions <code>new</code> and <code>create</code>, depending on the HTTP verb of the request. Since it’s pre-built, any “boring” code can be omitted and our <code>New</code> components looks like this:</p>
|
|
186
186
|
|
|
@@ -212,9 +212,9 @@
|
|
|
212
212
|
|
|
213
213
|
<p>This is enough to render a fully functional form that creates new users:</p>
|
|
214
214
|
|
|
215
|
-
<p><img src="/doc/imgs/intro-example-new.png"
|
|
215
|
+
<p><img src="/doc/imgs/intro-example-new.png" alt="New"> form</p>
|
|
216
216
|
|
|
217
|
-
<h2 id="
|
|
217
|
+
<h2 id="the-edit-component">The Edit component</h2>
|
|
218
218
|
|
|
219
219
|
<p>Just like <code>New</code>, <code>Edit</code> is a pre-built component that handles routing and resource manipulation for editing models, combinding the controller actions <code>edit</code> and <code>update</code> depending on the HTTP verb. It uses that same <code>Form</code> component we wrote above and thus the code is as simple as:</p>
|
|
220
220
|
|
|
@@ -224,9 +224,9 @@
|
|
|
224
224
|
|
|
225
225
|
<p>It then looks like this:</p>
|
|
226
226
|
|
|
227
|
-
<p><img src="/doc/imgs/intro-example-edit.png"
|
|
227
|
+
<p><img src="/doc/imgs/intro-example-edit.png" alt="Edit"> form</p>
|
|
228
228
|
|
|
229
|
-
<h2 id="
|
|
229
|
+
<h2 id="the-index-component">The Index component</h2>
|
|
230
230
|
|
|
231
231
|
<p>This component should list all users and provide buttons to manage them. We’ll build it from scratch and make it resourceful, where <code>@data</code> holds the ActiveRecord relation.</p>
|
|
232
232
|
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
|
|
274
274
|
<p>The result looks like this:</p>
|
|
275
275
|
|
|
276
|
-
<p><img src="/doc/imgs/intro-example-index.png"
|
|
276
|
+
<p><img src="/doc/imgs/intro-example-index.png" alt="Index"> component</p>
|
|
277
277
|
|
|
278
278
|
<p>Note how the admin’s delete button is disabled due to the feasibility framework. Pointing the mouse at it causes a tooltip saying: “Cannot destroy admins.”, as specified in the model’s prevention.</p>
|
|
279
279
|
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
</div></div>
|
|
282
282
|
|
|
283
283
|
<div id="footer">
|
|
284
|
-
Generated on
|
|
284
|
+
Generated on Tue Aug 18 14:36:33 2026 by
|
|
285
285
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
286
286
|
0.9.34 (ruby-3.4.9).
|
|
287
287
|
</div>
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
<div id="content"><div id='filecontents'>
|
|
61
61
|
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
62
|
|
|
63
|
-
<h1 id="
|
|
63
|
+
<h1 id="advanced-example">Advanced example</h1>
|
|
64
64
|
|
|
65
65
|
<p><a href="/doc/guide/example_md.html">example.md</a> shows the basics. This one combines patterns you hit in real apps: a custom form, feasibility, exposed intents, a CSV export endpoint, a <code>before_render</code> guard, and a virtual-model launch form for a background job.</p>
|
|
66
66
|
|
|
67
67
|
<p>Domain: invoicing. An <code>Invoice</code> has line items, can be locked, exported as CSV, and a background “send reminders” job can be launched from a non-persistent form.</p>
|
|
68
68
|
|
|
69
|
-
<h2 id="
|
|
69
|
+
<h2 id="the-models">The models</h2>
|
|
70
70
|
|
|
71
71
|
<pre class="code ruby"><code class="ruby"><span class='comment'># app/models/invoice.rb
|
|
72
72
|
</span><span class='kw'>class</span> <span class='const'>Invoice</span> <span class='op'><</span> <span class='const'>ApplicationRecord</span>
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
<span class='kw'>end</span>
|
|
100
100
|
</code></pre>
|
|
101
101
|
|
|
102
|
-
<h2 id="
|
|
102
|
+
<h2 id="index-with-a-csv-export-endpoint-and-exposed-intents">Index with a CSV export endpoint and exposed intents</h2>
|
|
103
103
|
|
|
104
104
|
<p>One component, two routes: the HTML list and a <code>.csv</code> download. The CSV intent is exposed so the layout renders a “Download CSV” button in the page header.</p>
|
|
105
105
|
|
|
@@ -137,14 +137,14 @@
|
|
|
137
137
|
|
|
138
138
|
<p>Notes:</p>
|
|
139
139
|
<ul><li>
|
|
140
|
-
<p><code>respond :csv</code> handles <code>GET /invoices.csv</code>. Because overriding <code>respond</code> <strong>skips the
|
|
140
|
+
<p><code>respond :csv</code> handles <code>GET /invoices.csv</code>. Because overriding <code>respond</code> <strong>skips the default <code>authorize</code></strong> (see <a href="/doc/guide/gotchas_md.html#3-overriding-respond-skips-authorization">gotchas.md</a>), the CSV branch re-checks the ability itself.</p>
|
|
141
141
|
</li><li>
|
|
142
142
|
<p><code>path: { format: :csv }</code> on the exposed intent makes its button point at <code>.csv</code>.</p>
|
|
143
143
|
</li><li>
|
|
144
|
-
<p>The layout renders exposed intents of <code>Compony.root_comp</code> — see
|
|
144
|
+
<p>The layout renders exposed intents of <code>Compony.root_comp</code> — see <a href="/doc/guide/intents_md.html#rendering-exposed-intents">intents.md</a>.</p>
|
|
145
145
|
</li></ul>
|
|
146
146
|
|
|
147
|
-
<h2 id="
|
|
147
|
+
<h2 id="a-custom-form-with-nested-line-items">A custom Form with nested line items</h2>
|
|
148
148
|
|
|
149
149
|
<p><code>Edit</code>/<code>New</code> look for <code>Components::Invoices::Form</code> by default. We write it with <code>accepts_nested_attributes_for</code> via <code>simple_form</code>‘s <code>simple_fields_for</code>, and whitelist the nested params with a raw <code>schema_line</code>.</p>
|
|
150
150
|
|
|
@@ -176,9 +176,9 @@
|
|
|
176
176
|
<span class='kw'>end</span>
|
|
177
177
|
</code></pre>
|
|
178
178
|
|
|
179
|
-
<p><code>schema_field :customer</code> (association name) lets Compony add <code>customer_id</code> automatically —
|
|
179
|
+
<p><code>schema_field :customer</code> (association name) lets Compony add <code>customer_id</code> automatically —passing <code>:customer_id</code> here would not work (<a href="/doc/guide/gotchas_md.html#4-schema_field-with-the-foreign-key-name">gotchas.md</a>).</p>
|
|
180
180
|
|
|
181
|
-
<h2 id="
|
|
181
|
+
<h2 id="edit-thin-plus-a-guard-and-a-custom-redirect">Edit: thin, plus a guard and a custom redirect</h2>
|
|
182
182
|
|
|
183
183
|
<p><code>Edit</code> inherits all CRUD wiring. We only add a <code>before_render</code> guard (independent of HTTP verb) and override where a successful save lands.</p>
|
|
184
184
|
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
|
|
201
201
|
<p><code>Components::Invoices::New</code>, <code>Show</code>, <code>Destroy</code> can stay empty — the pre-built parents do the work.</p>
|
|
202
202
|
|
|
203
|
-
<h2 id="
|
|
203
|
+
<h2 id="a-virtual-model-launch-form-for-a-background-job">A virtual-model launch form for a background job</h2>
|
|
204
204
|
|
|
205
205
|
<p>“Send reminders” should pop a small form (which customers? how many days overdue?) and, on submit, queue a job — nothing is persisted. Inherit <code>New</code>, back it with a <code>Compony::VirtualModel</code>, and take over <code>on_created_respond</code>.</p>
|
|
206
206
|
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
</div></div>
|
|
248
248
|
|
|
249
249
|
<div id="footer">
|
|
250
|
-
Generated on
|
|
250
|
+
Generated on Tue Aug 18 14:36:33 2026 by
|
|
251
251
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
252
252
|
0.9.34 (ruby-3.4.9).
|
|
253
253
|
</div>
|
data/doc/file.feasibility.html
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<div id="content"><div id='filecontents'>
|
|
61
61
|
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
62
|
|
|
63
|
-
<h1 id="
|
|
63
|
+
<h1 id="feasibility">Feasibility</h1>
|
|
64
64
|
|
|
65
65
|
<p>When a user has the permission to perform an action in general, but it is currently not feasible (for instance if the concerned object is incomplete, or if right now is not the right time to do the action), buttons pointing to that action should be disabled and a HTML <code>title</code> attribute should cause a tooltip explaining why this action cannot be performed right now.</p>
|
|
66
66
|
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
</div></div>
|
|
106
106
|
|
|
107
107
|
<div id="footer">
|
|
108
|
-
Generated on
|
|
108
|
+
Generated on Tue Aug 18 14:36:34 2026 by
|
|
109
109
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
110
110
|
0.9.34 (ruby-3.4.9).
|
|
111
111
|
</div>
|
data/doc/file.form.html
CHANGED
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
<p><a href="/doc/guide/pre_built_components_md.html">List of pre-built components</a></p>
|
|
64
64
|
</li></ul>
|
|
65
65
|
|
|
66
|
-
<h1 id="
|
|
66
|
+
<h1 id="pre-built-components-form">Pre-built components: Form</h1>
|
|
67
67
|
|
|
68
|
-
<p>This component holds a form and should only be instantiated by the <code>form_comp</code> call of a component that inherits from href="./with_form_md.html"></a>.</p>
|
|
68
|
+
<p>This component holds a form and should only be instantiated by the <code>form_comp</code> call of a component that inherits from <a href="./with_form_md.html"><code>WithForm</code></a>.</p>
|
|
69
69
|
|
|
70
|
-
<p><code>Compony::Components::Form</code> is an abstract base class for any components presenting a regular form. This class comes with a lot of tooling for rendering forms and inputs, as well as validating parameters. When the component is rendered, the Gem SimpleForm is used to create the actual form: <a href="https://github.com/heartcombo/simple_form">github.com/heartcombo/simple_form</a>.</p>
|
|
70
|
+
<p><code>Compony::Components::Form</code> is an abstract base class for any components presenting a regular form. This class comes with a lot of tooling for rendering forms and inputs, as well as validating parameters. When the component is rendered, the Gem SimpleForm is used to create the actual form: <a href="https://github.com/heartcombo/simple_form">https://github.com/heartcombo/simple_form</a>.</p>
|
|
71
71
|
|
|
72
|
-
<p>Parameters are structured like typical Rails forms. For instance, if you have a form for a <code>User</code> model and the attribute is <code>first_name</code>, the parameter looks like <code>user[first_name]=Tom</code>. In this case, we will call <code>user</code> the <code>schema_wrapper_key</code>. Parameters are validated using Schemacop: <a href="https://github.com/sitrox/schemacop">github.com/sitrox/schemacop</a>.</p>
|
|
72
|
+
<p>Parameters are structured like typical Rails forms. For instance, if you have a form for a <code>User</code> model and the attribute is <code>first_name</code>, the parameter looks like <code>user[first_name]=Tom</code>. In this case, we will call <code>user</code> the <code>schema_wrapper_key</code>. Parameters are validated using Schemacop: <a href="https://github.com/sitrox/schemacop">https://github.com/sitrox/schemacop</a>.</p>
|
|
73
73
|
|
|
74
74
|
<p>The following DSL calls are provided by the Form component:</p>
|
|
75
75
|
<ul><li>
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
|
|
114
114
|
<p>Both calls respect Cancancan’s <code>permitted_attributes</code> directive. This means that you can safely declare <code>field</code> and <code>schema_field</code> in a form that is shared among users with different kinds of permissions. If the current user is not allowed to access a field, the input will be omitted automatically. Further, the parameter validation will exclude that field, effectively disallowing that user from submitting that parameter.</p>
|
|
115
115
|
|
|
116
|
-
<h2 id="
|
|
116
|
+
<h2 id="handling-password-fields">Handling password fields</h2>
|
|
117
117
|
|
|
118
118
|
<p>When using Rails’ <code>has_secure_password</code> method, which typically generates the attributes accessors <code>:password</code> and <code>password_confirmation</code>, do not declare these two as fields in your User model.</p>
|
|
119
119
|
|
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
cannot :set_password, User # This prohibits setting and changing passwords of any user
|
|
151
151
|
</code></pre>
|
|
152
152
|
|
|
153
|
-
<h2 id="
|
|
153
|
+
<h2 id="dealing-with-multilingual-fields">Dealing with multilingual fields</h2>
|
|
154
154
|
|
|
155
155
|
<p>When using Gems such as <code>mobility</code>, Compony provides support for multilingual fields. For instance, assuming that a model has the attribute <code>label</code> translated in English and German, making <code>label</code> a virtual attribute reading either <code>label_en</code> and <code>label_de</code>, depending on the user’s language, Compony automatically generates a multilingual field if the following is used:</p>
|
|
156
156
|
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
</div></div>
|
|
186
186
|
|
|
187
187
|
<div id="footer">
|
|
188
|
-
Generated on
|
|
188
|
+
Generated on Tue Aug 18 14:36:34 2026 by
|
|
189
189
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
190
190
|
0.9.34 (ruby-3.4.9).
|
|
191
191
|
</div>
|
data/doc/file.generators.html
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<div id="content"><div id='filecontents'>
|
|
61
61
|
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
62
|
|
|
63
|
-
<h1 id="
|
|
63
|
+
<h1 id="rails-generators-provided-by-compony">Rails Generators provided by Compony</h1>
|
|
64
64
|
|
|
65
65
|
<p>To make your life easier and coding faster, Compony comes with two generators:</p>
|
|
66
66
|
<ul><li>
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<p><code>rails g components Users</code> will generate a set of the most used components.</p>
|
|
72
72
|
</li></ul>
|
|
73
73
|
|
|
74
|
-
<h3 id="
|
|
74
|
+
<h3 id="support-for-custom-base-components">Support for custom base components</h3>
|
|
75
75
|
|
|
76
76
|
<p>Generators will automatically detect your <code>BaseComponents</code> (see <a href="./inheritance_md.html#best-practice">Inheritance: best practice</a>).</p>
|
|
77
77
|
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
</div></div>
|
|
80
80
|
|
|
81
81
|
<div id="footer">
|
|
82
|
-
Generated on
|
|
82
|
+
Generated on Tue Aug 18 14:36:34 2026 by
|
|
83
83
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
84
84
|
0.9.34 (ruby-3.4.9).
|
|
85
85
|
</div>
|
data/doc/file.glossary.html
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
<div id="content"><div id='filecontents'>
|
|
61
61
|
<p><a href="/README_md.html#guide--documentation">Back to the guide</a></p>
|
|
62
62
|
|
|
63
|
-
<h1 id="
|
|
63
|
+
<h1 id="glossary">Glossary</h1>
|
|
64
64
|
|
|
65
65
|
<p>One-line definitions of Compony vocabulary. Deeper treatment is linked.</p>
|
|
66
66
|
|
|
@@ -74,131 +74,131 @@
|
|
|
74
74
|
<tbody>
|
|
75
75
|
<tr>
|
|
76
76
|
<td><strong>Component</strong></td>
|
|
77
|
-
<td>A Ruby class (
|
|
77
|
+
<td>A Ruby class (<code>Components::Family::Name</code>) bundling a route, controller action and view. See <a href="/doc/guide/basic_component_md.html">basic_component.md</a>.</td>
|
|
78
78
|
</tr>
|
|
79
79
|
<tr>
|
|
80
80
|
<td><strong>Family</strong></td>
|
|
81
|
-
<td>The plural namespace grouping a model’s components, analogous to a Rails controller (
|
|
81
|
+
<td>The plural namespace grouping a model’s components, analogous to a Rails controller (<code>Users</code>).</td>
|
|
82
82
|
</tr>
|
|
83
83
|
<tr>
|
|
84
|
-
<td
|
|
85
|
-
<td>The component’s own name, analogous to a Rails action (
|
|
84
|
+
<td><strong>Comp name</strong></td>
|
|
85
|
+
<td>The component’s own name, analogous to a Rails action (<code>show</code>).</td>
|
|
86
86
|
</tr>
|
|
87
87
|
<tr>
|
|
88
|
-
<td
|
|
88
|
+
<td><strong><code>setup</code></strong></td>
|
|
89
89
|
<td>Class-level block holding nearly all component config; parent’s runs before child’s.</td>
|
|
90
90
|
</tr>
|
|
91
91
|
<tr>
|
|
92
|
-
<td
|
|
93
|
-
<td>A named (
|
|
92
|
+
<td><strong>Content block</strong></td>
|
|
93
|
+
<td>A named (<code>:main</code> default) view block rendered via Dyny inside a RequestContext.</td>
|
|
94
94
|
</tr>
|
|
95
95
|
<tr>
|
|
96
|
-
<td
|
|
96
|
+
<td><strong><code>before_render</code></strong></td>
|
|
97
97
|
<td>Hook chain run before content; if it sets a response body (e.g. redirect) content is skipped.</td>
|
|
98
98
|
</tr>
|
|
99
99
|
<tr>
|
|
100
100
|
<td><strong>Standalone</strong></td>
|
|
101
|
-
<td>A
|
|
101
|
+
<td>A <code>standalone</code> config that makes Compony emit a Rails route for the component. See <a href="/doc/guide/standalone_md.html">standalone.md</a>.</td>
|
|
102
102
|
</tr>
|
|
103
103
|
<tr>
|
|
104
|
-
<td
|
|
105
|
-
<td>Identifier for one of several routes a component exposes;
|
|
104
|
+
<td><strong>Standalone name</strong></td>
|
|
105
|
+
<td>Identifier for one of several routes a component exposes; <code>nil</code> = the main one.</td>
|
|
106
106
|
</tr>
|
|
107
107
|
<tr>
|
|
108
108
|
<td><strong>Verb</strong></td>
|
|
109
|
-
<td>An HTTP method config inside a standalone (
|
|
109
|
+
<td>An HTTP method config inside a standalone (<code>verb :get do ... end</code>).</td>
|
|
110
110
|
</tr>
|
|
111
111
|
<tr>
|
|
112
|
-
<td
|
|
113
|
-
<td>Mandatory per-verb block; truthy grants access, falsy raises
|
|
112
|
+
<td><strong><code>authorize</code></strong></td>
|
|
113
|
+
<td>Mandatory per-verb block; truthy grants access, falsy raises <code>CanCan::AccessDenied</code>.</td>
|
|
114
114
|
</tr>
|
|
115
115
|
<tr>
|
|
116
|
-
<td
|
|
116
|
+
<td><strong><code>respond</code></strong></td>
|
|
117
117
|
<td>Per-verb block overriding the controller response; overriding it skips the default authorize step.</td>
|
|
118
118
|
</tr>
|
|
119
119
|
<tr>
|
|
120
120
|
<td><strong>Resourceful</strong></td>
|
|
121
|
-
<td>A component that auto-loads a record/relation into
|
|
121
|
+
<td>A component that auto-loads a record/relation into <code>@data</code> (mixin or pre-built parent). See <a href="/doc/guide/resourceful_md.html">resourceful.md</a>.</td>
|
|
122
122
|
</tr>
|
|
123
123
|
<tr>
|
|
124
|
-
<td
|
|
124
|
+
<td><strong><code>@data</code></strong></td>
|
|
125
125
|
<td>The record (or AR relation) a resourceful component operates on.</td>
|
|
126
126
|
</tr>
|
|
127
127
|
<tr>
|
|
128
|
-
<td
|
|
128
|
+
<td><strong><code>data_class</code></strong></td>
|
|
129
129
|
<td>The model class a resourceful component expects; defaults from the family name.</td>
|
|
130
130
|
</tr>
|
|
131
131
|
<tr>
|
|
132
|
-
<td
|
|
133
|
-
<td
|
|
132
|
+
<td><strong>Lifecycle hooks</strong></td>
|
|
133
|
+
<td><code>load_data → after_load_data → authorize → assign_attributes → after_assign_attributes → store_data</code>.</td>
|
|
134
134
|
</tr>
|
|
135
135
|
<tr>
|
|
136
136
|
<td><strong>Intent</strong></td>
|
|
137
|
-
<td>A gateway object to a target component carrying context (model, path, feasibility, label). See
|
|
137
|
+
<td>A gateway object to a target component carrying context (model, path, feasibility, label). See <a href="/doc/guide/intents_md.html">intents.md</a>.</td>
|
|
138
138
|
</tr>
|
|
139
139
|
<tr>
|
|
140
|
-
<td
|
|
140
|
+
<td><strong>Exposed intent</strong></td>
|
|
141
141
|
<td>An intent a component declares for its parent/layout to render (e.g. an actions toolbar).</td>
|
|
142
142
|
</tr>
|
|
143
143
|
<tr>
|
|
144
|
-
<td
|
|
144
|
+
<td><strong><code>Compony.path</code></strong></td>
|
|
145
145
|
<td>Helper that builds a Rails path string via an intent (use for redirects).</td>
|
|
146
146
|
</tr>
|
|
147
147
|
<tr>
|
|
148
|
-
<td
|
|
148
|
+
<td><strong><code>render_intent</code></strong></td>
|
|
149
149
|
<td>Content/view helper that renders a link or button to another component.</td>
|
|
150
150
|
</tr>
|
|
151
151
|
<tr>
|
|
152
|
-
<td
|
|
152
|
+
<td><strong><code>render_sub_comp</code></strong></td>
|
|
153
153
|
<td>Content helper that instantiates and nests another component.</td>
|
|
154
154
|
</tr>
|
|
155
155
|
<tr>
|
|
156
|
-
<td
|
|
157
|
-
<td>A component instantiated inside another; the outer one is its
|
|
156
|
+
<td><strong>Sub comp / parent comp</strong></td>
|
|
157
|
+
<td>A component instantiated inside another; the outer one is its <code>parent_comp</code>.</td>
|
|
158
158
|
</tr>
|
|
159
159
|
<tr>
|
|
160
|
-
<td
|
|
161
|
-
<td>The top component of the current render tree (no parent);
|
|
160
|
+
<td><strong>Root comp</strong></td>
|
|
161
|
+
<td>The top component of the current render tree (no parent); <code>Compony.root_comp</code>.</td>
|
|
162
162
|
</tr>
|
|
163
163
|
<tr>
|
|
164
164
|
<td><strong>RequestContext</strong></td>
|
|
165
|
-
<td>Dslblend object content blocks run in: providers are the component, controller, helpers. See
|
|
165
|
+
<td>Dslblend object content blocks run in: providers are the component, controller, helpers. See <a href="/doc/guide/internal_datastructures_md.html">internal_datastructures.md</a>.</td>
|
|
166
166
|
</tr>
|
|
167
167
|
<tr>
|
|
168
168
|
<td><strong>Backfire</strong></td>
|
|
169
169
|
<td>Dslblend mechanism copying instance vars set in a block back onto the component.</td>
|
|
170
170
|
</tr>
|
|
171
171
|
<tr>
|
|
172
|
-
<td
|
|
173
|
-
<td>A presenter component for an intent;
|
|
172
|
+
<td><strong>Button / style</strong></td>
|
|
173
|
+
<td>A presenter component for an intent; <code>style</code> (<code>:css_button</code>, <code>:link</code>, custom) selects the class.</td>
|
|
174
174
|
</tr>
|
|
175
175
|
<tr>
|
|
176
176
|
<td><strong>Feasibility</strong></td>
|
|
177
|
-
<td>Framework where model
|
|
177
|
+
<td>Framework where model <code>prevent</code> blocks disable buttons/links to an action with a reason. See <a href="/doc/guide/feasibility_md.html">feasibility.md</a>.</td>
|
|
178
178
|
</tr>
|
|
179
179
|
<tr>
|
|
180
|
-
<td
|
|
180
|
+
<td><strong><code>prevent</code></strong></td>
|
|
181
181
|
<td>Model class DSL declaring a feasibility prevention for one or more actions.</td>
|
|
182
182
|
</tr>
|
|
183
183
|
<tr>
|
|
184
184
|
<td><strong>Field</strong></td>
|
|
185
|
-
<td>A model-level declaration (
|
|
185
|
+
<td>A model-level declaration (<code>field :name, :type</code>) of a UI-relevant attribute and its formatting. See <a href="/doc/guide/model_fields_md.html">model_fields.md</a>.</td>
|
|
186
186
|
</tr>
|
|
187
187
|
<tr>
|
|
188
|
-
<td
|
|
189
|
-
<td>Declares a model conceptually part of another, adjusting redirects/top actions. See
|
|
188
|
+
<td><strong>Ownership / <code>owned_by</code></strong></td>
|
|
189
|
+
<td>Declares a model conceptually part of another, adjusting redirects/top actions. See <a href="/doc/guide/ownership_md.html">ownership.md</a>.</td>
|
|
190
190
|
</tr>
|
|
191
191
|
<tr>
|
|
192
|
-
<td
|
|
193
|
-
<td>A non-persistent ActiveType-backed model usable as a form target. See
|
|
192
|
+
<td><strong>Virtual model</strong></td>
|
|
193
|
+
<td>A non-persistent ActiveType-backed model usable as a form target. See <a href="/doc/guide/virtual_models_md.html">virtual_models.md</a>.</td>
|
|
194
194
|
</tr>
|
|
195
195
|
<tr>
|
|
196
196
|
<td><strong>Dyny</strong></td>
|
|
197
|
-
<td>The HTML-as-Ruby templating gem content blocks are written in (
|
|
197
|
+
<td>The HTML-as-Ruby templating gem content blocks are written in (<a href="https://github.com/kalsan/dyny">repo</a>).</td>
|
|
198
198
|
</tr>
|
|
199
199
|
<tr>
|
|
200
|
-
<td
|
|
201
|
-
<td>A component never routed directly, only inherited from (e.g. an app’s
|
|
200
|
+
<td><strong>Abstract component</strong></td>
|
|
201
|
+
<td>A component never routed directly, only inherited from (e.g. an app’s <code>BaseComponents::*</code>).</td>
|
|
202
202
|
</tr>
|
|
203
203
|
</tbody>
|
|
204
204
|
</table>
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
</div></div>
|
|
208
208
|
|
|
209
209
|
<div id="footer">
|
|
210
|
-
Generated on
|
|
210
|
+
Generated on Tue Aug 18 14:36:35 2026 by
|
|
211
211
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
212
212
|
0.9.34 (ruby-3.4.9).
|
|
213
213
|
</div>
|