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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +36 -1
  3. data/CHANGELOG.md +31 -0
  4. data/CLAUDE.md +85 -0
  5. data/Gemfile.lock +1 -1
  6. data/README.md +13 -3
  7. data/VERSION +1 -1
  8. data/compony.gemspec +3 -3
  9. data/doc/ComponentGenerator.html +1 -1
  10. data/doc/Components.html +1 -1
  11. data/doc/ComponentsGenerator.html +1 -1
  12. data/doc/Compony/Component.html +54 -54
  13. data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
  14. data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
  15. data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +109 -70
  16. data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +64 -28
  17. data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
  18. data/doc/Compony/ComponentMixins/Default.html +1 -1
  19. data/doc/Compony/ComponentMixins/Resourceful.html +213 -74
  20. data/doc/Compony/ComponentMixins.html +1 -1
  21. data/doc/Compony/Components/Buttons/CssButton.html +1 -1
  22. data/doc/Compony/Components/Buttons/Link.html +1 -1
  23. data/doc/Compony/Components/Buttons.html +1 -1
  24. data/doc/Compony/Components/Destroy.html +83 -29
  25. data/doc/Compony/Components/Edit.html +110 -38
  26. data/doc/Compony/Components/Form.html +551 -208
  27. data/doc/Compony/Components/Index.html +1 -1
  28. data/doc/Compony/Components/List.html +3 -3
  29. data/doc/Compony/Components/New.html +110 -38
  30. data/doc/Compony/Components/Show.html +1 -1
  31. data/doc/Compony/Components/WithForm.html +194 -47
  32. data/doc/Compony/Components.html +1 -1
  33. data/doc/Compony/ControllerMixin.html +1 -1
  34. data/doc/Compony/Engine.html +1 -1
  35. data/doc/Compony/Intent.html +2 -2
  36. data/doc/Compony/ManageIntentsDsl.html +1 -1
  37. data/doc/Compony/MethodAccessibleHash.html +1 -1
  38. data/doc/Compony/ModelFields/Anchormodel.html +1 -1
  39. data/doc/Compony/ModelFields/Association.html +1 -1
  40. data/doc/Compony/ModelFields/Attachment.html +1 -1
  41. data/doc/Compony/ModelFields/Base.html +1 -1
  42. data/doc/Compony/ModelFields/Boolean.html +1 -1
  43. data/doc/Compony/ModelFields/Color.html +1 -1
  44. data/doc/Compony/ModelFields/Currency.html +1 -1
  45. data/doc/Compony/ModelFields/Date.html +1 -1
  46. data/doc/Compony/ModelFields/Datetime.html +1 -1
  47. data/doc/Compony/ModelFields/Decimal.html +1 -1
  48. data/doc/Compony/ModelFields/Email.html +1 -1
  49. data/doc/Compony/ModelFields/Float.html +1 -1
  50. data/doc/Compony/ModelFields/Integer.html +1 -1
  51. data/doc/Compony/ModelFields/Percentage.html +1 -1
  52. data/doc/Compony/ModelFields/Phone.html +1 -1
  53. data/doc/Compony/ModelFields/RichText.html +1 -1
  54. data/doc/Compony/ModelFields/String.html +1 -1
  55. data/doc/Compony/ModelFields/Text.html +1 -1
  56. data/doc/Compony/ModelFields/Time.html +1 -1
  57. data/doc/Compony/ModelFields/Url.html +1 -1
  58. data/doc/Compony/ModelFields.html +1 -1
  59. data/doc/Compony/ModelMixin.html +1 -1
  60. data/doc/Compony/NaturalOrdering.html +1 -1
  61. data/doc/Compony/RequestContext.html +1 -1
  62. data/doc/Compony/Version.html +1 -1
  63. data/doc/Compony/ViewHelpers.html +1 -1
  64. data/doc/Compony/VirtualModel.html +1 -1
  65. data/doc/Compony.html +1 -1
  66. data/doc/ComponyController.html +1 -1
  67. data/doc/_index.html +97 -1
  68. data/doc/file.CHANGELOG.html +758 -0
  69. data/doc/file.README.html +25 -4
  70. data/doc/file.basic_component.html +314 -0
  71. data/doc/file.cookbook.html +189 -0
  72. data/doc/file.destroy.html +105 -0
  73. data/doc/file.dsl_reference.html +672 -0
  74. data/doc/file.edit.html +109 -0
  75. data/doc/file.example.html +291 -0
  76. data/doc/file.example_advanced.html +257 -0
  77. data/doc/file.feasibility.html +115 -0
  78. data/doc/file.form.html +195 -0
  79. data/doc/file.generators.html +89 -0
  80. data/doc/file.glossary.html +217 -0
  81. data/doc/file.gotchas.html +222 -0
  82. data/doc/file.index.html +135 -0
  83. data/doc/file.inheritance.html +136 -0
  84. data/doc/file.installation.html +115 -0
  85. data/doc/file.integrations.html +218 -0
  86. data/doc/file.intents.html +265 -0
  87. data/doc/file.internal_datastructures.html +129 -0
  88. data/doc/file.list.html +253 -0
  89. data/doc/file.maintaining.html +127 -0
  90. data/doc/file.model_fields.html +137 -0
  91. data/doc/file.nesting.html +237 -0
  92. data/doc/file.new.html +109 -0
  93. data/doc/file.ownership.html +98 -0
  94. data/doc/file.patterns.html +669 -0
  95. data/doc/file.pre_built_components.html +99 -0
  96. data/doc/file.resourceful.html +181 -0
  97. data/doc/file.show.html +158 -0
  98. data/doc/file.standalone.html +233 -0
  99. data/doc/file.virtual_models.html +117 -0
  100. data/doc/file.with_form.html +157 -0
  101. data/doc/file_list.html +160 -0
  102. data/doc/guide/cookbook.md +41 -0
  103. data/doc/guide/dsl_reference.md +155 -0
  104. data/doc/guide/example_advanced.md +209 -0
  105. data/doc/guide/generators.md +1 -1
  106. data/doc/guide/glossary.md +42 -0
  107. data/doc/guide/gotchas.md +125 -0
  108. data/doc/guide/maintaining.md +64 -0
  109. data/doc/guide/patterns.md +681 -0
  110. data/doc/guide/pre_built_components/edit.md +1 -1
  111. data/doc/guide/pre_built_components/index.md +64 -1
  112. data/doc/guide/pre_built_components/list.md +111 -7
  113. data/doc/guide/pre_built_components/show.md +57 -2
  114. data/doc/guide/pre_built_components/with_form.md +56 -9
  115. data/doc/guide/pre_built_components.md +7 -2
  116. data/doc/guide/standalone.md +16 -1
  117. data/doc/index.html +25 -4
  118. data/doc/integrations.md +61 -0
  119. data/doc/llms.txt +62 -0
  120. data/doc/top-level-namespace.html +1 -1
  121. data/lib/compony/component.rb +8 -3
  122. data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +32 -15
  123. data/lib/compony/component_mixins/default/standalone/verb_dsl.rb +11 -3
  124. data/lib/compony/component_mixins/resourceful.rb +30 -16
  125. data/lib/compony/components/destroy.rb +21 -1
  126. data/lib/compony/components/edit.rb +25 -1
  127. data/lib/compony/components/form.rb +63 -21
  128. data/lib/compony/components/list.rb +1 -1
  129. data/lib/compony/components/new.rb +25 -1
  130. data/lib/compony/components/with_form.rb +20 -5
  131. data/lib/compony/intent.rb +1 -1
  132. metadata +43 -1
@@ -0,0 +1,99 @@
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: pre_built_components
8
+
9
+ &mdash; 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 = "pre_built_components";
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> &raquo;
40
+ <span class="title">File: pre_built_components</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-Pre-built+components+shipped+with+Compony">Pre-built components shipped with Compony</h1>
64
+
65
+ <p>Compony comes with a few pre-built components that cover the most common cases that can be speed up development. They are meant to be inherited from and the easiest way to do this is by using the <a href="./generators_md.html">provided Rails generators</a> <code>rails g component ...</code>.</p>
66
+
67
+ <p>The pre-built components can be found in the module <code>Compony::Components</code>. They ship a sensible, UI-agnostic default (plain HTML, no styling) — you typically inherit from them in an app base layer that adds your UI framework’s markup (see <a href="./patterns_md.html#1-the-app-base-component-layer">Real-world patterns</a>). <code>Show</code> and <code>Index</code> are intentionally minimal because their presentation depends heavily on your UI framework; they are easy to override (see the <a href="./example_md.html">example</a>).</p>
68
+
69
+ <p>In the following, the pre-built components currently shipped with Compony are presented:</p>
70
+ <ul><li>
71
+ <p><a href="./pre_built_components/show_md.html">Show</a>: Compony’s equivalent to Rail’s <code>show</code> controller action</p>
72
+ </li><li>
73
+ <p><a href="./pre_built_components/index_md.html">Index</a>: Compony’s equivalent to Rail’s <code>index</code> controller action</p>
74
+ </li><li>
75
+ <p><a href="./pre_built_components/list_md.html">List</a>: Compony’s equivalent to Rail’s <code>_list</code> partial</p>
76
+ </li><li>
77
+ <p><a href="./pre_built_components/destroy_md.html">Destroy</a>: Compony’s equivalent to Rail’s <code>destroy</code> controller action</p>
78
+ </li><li>
79
+ <p><a href="./pre_built_components/with_form_md.html">WithForm</a>: A base class for components containing and submitting forms</p>
80
+ </li><li>
81
+ <p><a href="./pre_built_components/form_md.html">Form</a>: Compony’s equivalent to Rail’s <code>_form</code> partial</p>
82
+ </li><li>
83
+ <p><a href="./pre_built_components/new_md.html">New</a>: Compony’s equivalent to Rail’s <code>new</code> and <code>create</code> controller action</p>
84
+ </li><li>
85
+ <p><a href="./pre_built_components/edit_md.html">Edit</a>: Compony’s equivalent to Rail’s <code>edit</code> and <code>update</code> controller action</p>
86
+ </li></ul>
87
+
88
+ <p><a href="/README_md.html#guide--documentation">Guide index</a></p>
89
+ </div></div>
90
+
91
+ <div id="footer">
92
+ Generated on Mon May 18 13:55:33 2026 by
93
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
94
+ 0.9.34 (ruby-3.3.5).
95
+ </div>
96
+
97
+ </div>
98
+ </body>
99
+ </html>
@@ -0,0 +1,181 @@
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: resourceful
8
+
9
+ &mdash; 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 = "resourceful";
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> &raquo;
40
+ <span class="title">File: resourceful</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-Resourceful+components">Resourceful components</h1>
64
+
65
+ <p>So far, we have mainly seen how to present static content, without considering how loading and storing data is handled. Whenever a component is about data, be it a collection (e.g. index, list) or a single instance (e.g. new, show, edit, destroy, form), that component typically becomes resourceful. In order to implement a resourceful component, include the mixin <code>Compony::ComponentMixins::Resourceful</code>.</p>
66
+
67
+ <p>Resourceful components use an instance variable <code>@data</code> and provide a reader <code>data</code> for it. As a convention, always store the data the component “is about” in this variable.</p>
68
+
69
+ <p>Further, the class of which <code>data</code> should be can be specified and retrieved by using <code>data_class</code>. By default, <code>data_class</code> is inferred from the component’s family name, i.e. <code>Components::User::Show</code> will automatically return <code>User</code> as <code>data_class</code>.</p>
70
+
71
+ <p>The mixin adds extra hooks that can be used to store logic that can be executed in the request context when the component is rendered standalone. The formulation of that sentence is important, as the decision which of these blocks are executed depends on the verb DSL. But before elaborating on that, let’s first look at all the available hooks provided by the Resourceful mixin:</p>
72
+ <ul><li>
73
+ <p><code>load_data</code>: Important. Specify a block that assigns something to <code>@data</code> here. The block will be run before authorization - thus, you can check <code>@data</code> for authorizing (e.g. <code>can?(:read, @data)</code>).</p>
74
+ </li><li>
75
+ <p><code>after_load_data</code>: Optional. If a block is specified, it is run immediately after <code>load_data</code>. This is useful if you inherit from a component that loads data but you need to alter something, e.g. refining a collection.</p>
76
+ </li><li>
77
+ <p><code>assign_attributes</code>: Important for components that alter data, e.g. New, Edit. Specify a block that assigns attributes to your model from <code>load_data</code>. The model is now dirty, which is important: <strong>do not save your model here</strong>, as authorization has not yet been performed. Also, <strong>do not forget to validate params before assigning them to attributes</strong>.</p>
78
+ </li><li>
79
+ <p><code>after_assign_attributes</code>: Optional. If a block is specified, it is run immediately after <code>assign_attributes</code>. Its usage is similar to that of <code>after_load_data</code>.</p>
80
+ </li><li>
81
+ <p>(At this point, your <code>authorize</code> block is executed, throwing a <code>CanCan::AccessDenied</code> exception causing HTTP 403 not authorized if the block returns false.)</p>
82
+ </li><li>
83
+ <p><code>store_data</code>: Important for components that alter data, e.g. New, Edit. This is where you save your model stored in <code>@data</code> to the database.</p>
84
+ </li></ul>
85
+
86
+ <p>Another important aspect of the Resourceful mixin is that it also <strong>extends the Verb DSL</strong> available in the component. The added calls are:</p>
87
+ <ul><li>
88
+ <p><code>load_data</code></p>
89
+ </li><li>
90
+ <p><code>assign_attributes</code></p>
91
+ </li><li>
92
+ <p><code>store_data</code></p>
93
+ </li></ul>
94
+
95
+ <p>Unlike the calls above, which are global for the entire component, the ones in the Verb DSL are on a per-verb basis, same as the <code>authorize</code> call. If the same hook is both given as a global hook and in the Verb DSL, the Verb DSL hook overwrites the global one. The rule of thumb on where to place logic is:</p>
96
+ <ul><li>
97
+ <p>If multiple verbs use the same logic for a hook, place it in the global hook. For example, let us consider an Edit component: if GET is called on it, the model is loaded and parameters are assigned to it in order to fill the form’s inputs. If PATCH is called, the exact same thing is done before attempting to save the model. In this case, you would implement both <code>load_data</code> and <code>assign_attributes</code> as global hooks.</p>
98
+ </li><li>
99
+ <p>If a hook is specific to a single verb, place it in the verb config.</p>
100
+ </li></ul>
101
+
102
+ <p>Let’s build an example of a simplified Destroy component. In practice, you’d instead inherit from <code>Compony::Components::Destroy</code>. However, for the sake of demonstration, we will implement it from scratch:</p>
103
+
104
+ <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'>Destroy</span> <span class='op'>&lt;</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/Component.html" title="Compony::Component (class)">Component</a></span></span>
105
+ <span class='comment'># Make the component resourceful
106
+ </span> <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/ComponentMixins.html" title="Compony::ComponentMixins (module)">ComponentMixins</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Compony/ComponentMixins/Resourceful.html" title="Compony::ComponentMixins::Resourceful (module)">Resourceful</a></span></span>
107
+
108
+ <span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
109
+ <span class='comment'># Let the path be of the form users/42/destroy
110
+ </span> <span class='id identifier rubyid_standalone'>standalone</span> <span class='label'>path:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>users/:id/destroy</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
111
+ <span class='id identifier rubyid_verb'>verb</span> <span class='symbol'>:get</span> <span class='kw'>do</span>
112
+ <span class='comment'># In the case of a GET request, ask for confirmation, not deleting anything.
113
+ </span> <span class='comment'># Nevertheless, we should authorize :destroy, not :read.
114
+ </span> <span class='comment'># Reason: this way, buttons pointing to this component will not be shown
115
+ </span> <span class='comment'># to users which lack the permission to destroy @data.
116
+ </span> <span class='id identifier rubyid_authorize'>authorize</span> <span class='lbrace'>{</span> <span class='id identifier rubyid_can?'>can?</span><span class='lparen'>(</span><span class='symbol'>:destroy</span><span class='comma'>,</span> <span class='ivar'>@data</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
117
+ <span class='kw'>end</span>
118
+
119
+ <span class='id identifier rubyid_verb'>verb</span> <span class='symbol'>:delete</span> <span class='kw'>do</span>
120
+ <span class='comment'># In the case of a DELETE request, the record will be destroyed.
121
+ </span> <span class='id identifier rubyid_authorize'>authorize</span> <span class='lbrace'>{</span> <span class='id identifier rubyid_can?'>can?</span><span class='lparen'>(</span><span class='symbol'>:destroy</span><span class='comma'>,</span> <span class='ivar'>@data</span><span class='rparen'>)</span> <span class='rbrace'>}</span>
122
+ <span class='id identifier rubyid_store_data'>store_data</span> <span class='lbrace'>{</span> <span class='ivar'>@data</span><span class='period'>.</span><span class='id identifier rubyid_destroy!'>destroy!</span> <span class='rbrace'>}</span>
123
+ <span class='comment'># We overwrite the respond block because we want to redirect, not render
124
+ </span> <span class='id identifier rubyid_respond'>respond</span> <span class='kw'>do</span>
125
+ <span class='id identifier rubyid_flash'>flash</span><span class='period'>.</span><span class='id identifier rubyid_notice'>notice</span> <span class='op'>=</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='embexpr_beg'>#{</span><span class='ivar'>@data</span><span class='period'>.</span><span class='id identifier rubyid_label'>label</span><span class='embexpr_end'>}</span><span class='tstring_content'> was deleted.</span><span class='tstring_end'>&quot;</span></span>
126
+ <span class='id identifier rubyid_redirect_to'>redirect_to</span> <span class='const'><span class='object_link'><a href="Compony.html" title="Compony (module)">Compony</a></span></span><span class='period'>.</span><span class='id identifier rubyid_path'><span class='object_link'><a href="Compony.html#path-class_method" title="Compony.path (method)">path</a></span></span><span class='lparen'>(</span><span class='symbol'>:index</span><span class='comma'>,</span> <span class='symbol'>:users</span><span class='rparen'>)</span>
127
+ <span class='kw'>end</span>
128
+ <span class='kw'>end</span>
129
+ <span class='kw'>end</span>
130
+
131
+ <span class='comment'># Resourceful components have a default `load_data` block that loads the model.
132
+ </span> <span class='comment'># Therefore, the default behavior is already set to:
133
+ </span> <span class='comment'># load_data { @data = User.find(params[:id]) }
134
+ </span>
135
+ <span class='id identifier rubyid_label'>label</span><span class='lparen'>(</span><span class='symbol'>:short</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid__'>_</span><span class='op'>|</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Delete</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span>
136
+ <span class='id identifier rubyid_label'>label</span><span class='lparen'>(</span><span class='symbol'>:long</span><span class='rparen'>)</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_data'>data</span><span class='op'>|</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Delete </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_data'>data</span><span class='period'>.</span><span class='id identifier rubyid_label'>label</span><span class='embexpr_end'>}</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span>
137
+ <span class='id identifier rubyid_content'>content</span> <span class='kw'>do</span>
138
+ <span class='id identifier rubyid_h1'>h1</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Are you sure to delete </span><span class='embexpr_beg'>#{</span><span class='ivar'>@data</span><span class='period'>.</span><span class='id identifier rubyid_label'>label</span><span class='embexpr_end'>}</span><span class='tstring_content'>?</span><span class='tstring_end'>&quot;</span></span>
139
+ <span class='id identifier rubyid_div'>div</span> <span class='id identifier rubyid_render_intent'>render_intent</span><span class='lparen'>(</span><span class='symbol'>:destroy</span><span class='comma'>,</span> <span class='ivar'>@data</span><span class='comma'>,</span> <span class='label'>label:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Yes, delete</span><span class='tstring_end'>&#39;</span></span><span class='comma'>,</span> <span class='label'>method:</span> <span class='symbol'>:delete</span><span class='rparen'>)</span>
140
+ <span class='kw'>end</span>
141
+ <span class='kw'>end</span>
142
+ <span class='kw'>end</span>
143
+ </code></pre>
144
+
145
+ <h2 id="label-Complete+resourceful+lifecycle">Complete resourceful lifecycle</h2>
146
+
147
+ <p>This graph documents a typical resourceful lifecycle according to which Compony’s <a href="./pre_built_components_md.html">pre-built components</a> are implemented.</p>
148
+ <ul><li>
149
+ <p><code>load_data</code> creates or fetches the resource from the database.</p>
150
+ </li><li>
151
+ <p><code>after_load_data</code> can refine the resource, e.g. add scopes to a relation.</p>
152
+ </li><li>
153
+ <p><code>assign_attributes</code> takes the HTTP parameters, validates them and assigns them to the resource.</p>
154
+ </li><li>
155
+ <p><code>after_assign_attributes</code> can refine the assigned resource, e.g. provide defaults for blank attributes.</p>
156
+ </li><li>
157
+ <p><code>authorize</code> is called.</p>
158
+ </li><li>
159
+ <p><code>store_data</code> creates/updates/destroys the resource.</p>
160
+ </li><li>
161
+ <p><code>respond</code> typically shows a flash and redirects to another component.</p>
162
+ </li></ul>
163
+
164
+ <p><img src="/doc/resourceful_lifecycle.png"></p>
165
+
166
+ <h2 id="label-Nesting+resourceful+components">Nesting resourceful components</h2>
167
+
168
+ <p>The <a href="/doc/guide/intents_md.html">Intent</a> API makes it very easy to pass a resource to nested components. For more details, refer to <a href="/doc/guide/nesting_md.html#rendering-list-as-sub-comp-in-show">this example</a>.</p>
169
+
170
+ <p><a href="/README_md.html#guide--documentation">Guide index</a></p>
171
+ </div></div>
172
+
173
+ <div id="footer">
174
+ Generated on Mon May 18 13:55:33 2026 by
175
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
176
+ 0.9.34 (ruby-3.3.5).
177
+ </div>
178
+
179
+ </div>
180
+ </body>
181
+ </html>
@@ -0,0 +1,158 @@
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: show
8
+
9
+ &mdash; 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 = "show";
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> &raquo;
40
+ <span class="title">File: show</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+Show">Pre-built components: Show</h1>
67
+
68
+ <p><code>Compony::Components::Show</code> is a resourceful standalone component corresponding to a Rails <code>show</code> action. It loads <code>@data</code> by <code>:id</code> and presents its fields.</p>
69
+
70
+ <h2 id="label-What+it+does+by+default">What it does by default</h2>
71
+
72
+ <p>From <code>lib/compony/components/show.rb</code>:</p>
73
+ <ul><li>
74
+ <p><strong>Route:</strong> <code>standalone path: &quot;/#{family_name}/:id&quot;</code> with an <code>:id</code> constraint that accepts integer <strong>or</strong> UUID ids, <code>verb :get</code> authorized by <code>can?(:show, @data)</code>.</p>
75
+ </li><li>
76
+ <p><strong>Labels:</strong> long = <code>data.label</code>; short = a generic translated “Show”.</p>
77
+ </li><li>
78
+ <p><strong>Exposed intents:</strong> <code>:edit</code> and <code>:destroy</code> for <code>@data</code>, plus a <code>:back_to_owner</code> intent if the model is <a href="/doc/guide/ownership_md.html">owned</a>.</p>
79
+ </li><li>
80
+ <p><strong>Content blocks:</strong></p>
81
+ </li><li>
82
+ <p><code>:label</code> → <code>h2 component.label</code></p>
83
+ </li><li>
84
+ <p><code>:main</code> → renders the <code>:data</code> block (override <code>:main</code> to wrap <code>:data</code> in a card etc.)</p>
85
+ </li><li>
86
+ <p><code>:data</code> (hidden) → if no columns were declared, calls <code>all_field_columns(@data)</code>, then renders a two-column table of label/value per permitted field.</p>
87
+ </li></ul>
88
+
89
+ <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'>Show</span> <span class='op'>&lt;</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/Show.html" title="Compony::Components::Show (class)">Show</a></span></span><span class='semicolon'>;</span> <span class='kw'>end</span> <span class='comment'># fully functional
90
+ </span></code></pre>
91
+
92
+ <h2 id="label-Column+DSL">Column DSL</h2>
93
+
94
+ <p><code>Show</code> shares a <code>column</code>/<code>columns</code> DSL with href="./list_md.html"></a> (here “column” means an attribute row, since Show renders one record).</p>
95
+
96
+ <table role="table">
97
+ <thead>
98
+ <tr>
99
+ <th>Method</th>
100
+ <th>Signature</th>
101
+ <th>Description</th>
102
+ </tr>
103
+ </thead>
104
+ <tbody>
105
+ <tr>
106
+ <td>‘column`</td>
107
+ <td>‘column(:name, label: nil, class: nil, link_opts: {}, link_to_component: :show) { |record| … }`</td>
108
+ <td>Add/define one attribute row. Without a block, treated as a model field; the block (instance-exec’d per record) supplies the value.</td>
109
+ </tr>
110
+ <tr>
111
+ <td>‘columns`</td>
112
+ <td>‘columns(:a, :b, **shared_kwargs)`</td>
113
+ <td>Bulk ‘column`.</td>
114
+ </tr>
115
+ <tr>
116
+ <td>‘all_field_columns`</td>
117
+ <td>‘all_field_columns(@data)`</td>
118
+ <td>Add a column for every model field (the default when none declared).</td>
119
+ </tr>
120
+ <tr>
121
+ <td>‘skip_column`</td>
122
+ <td>‘skip_column(:name)`</td>
123
+ <td>Drop an inherited column. When nesting Show in a parent, prefer the constructor’s ‘skip_columns:` kwarg.</td>
124
+ </tr>
125
+ </tbody>
126
+ </table>
127
+
128
+ <p>Field columns are only rendered if the current ability permits <code>:show</code> on that attribute; a <code>nil</code> value hides the row.</p>
129
+
130
+ <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'>Show</span> <span class='op'>&lt;</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/Show.html" title="Compony::Components::Show (class)">Show</a></span></span>
131
+ <span class='id identifier rubyid_setup'>setup</span> <span class='kw'>do</span>
132
+ <span class='id identifier rubyid_columns'>columns</span> <span class='symbol'>:name</span><span class='comma'>,</span> <span class='symbol'>:email</span><span class='comma'>,</span> <span class='symbol'>:created_at</span>
133
+ <span class='id identifier rubyid_column'>column</span> <span class='symbol'>:status</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_user'>user</span><span class='op'>|</span> <span class='comment'># custom computed row
134
+ </span> <span class='id identifier rubyid_user'>user</span><span class='period'>.</span><span class='id identifier rubyid_active?'>active?</span> <span class='op'>?</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Active</span><span class='tstring_end'>&#39;</span></span> <span class='op'>:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Disabled</span><span class='tstring_end'>&#39;</span></span>
135
+ <span class='kw'>end</span>
136
+ <span class='id identifier rubyid_skip_column'>skip_column</span> <span class='symbol'>:created_at</span> <span class='comment'># if inherited and unwanted
137
+ </span>
138
+ <span class='id identifier rubyid_content'>content</span> <span class='kw'>do</span> <span class='comment'># wrap :data in app chrome
139
+ </span> <span class='id identifier rubyid_div'>div</span> <span class='label'>class:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>card card-body</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
140
+ <span class='id identifier rubyid_content'>content</span> <span class='symbol'>:data</span>
141
+ <span class='kw'>end</span>
142
+ <span class='kw'>end</span>
143
+ <span class='kw'>end</span>
144
+ <span class='kw'>end</span>
145
+ </code></pre>
146
+
147
+ <p>UUID/string ids work out of the box thanks to the route constraint. For nesting a Show (or its <code>:data</code>) inside another component see <a href="/doc/guide/nesting_md.html">Nesting</a>; for the app base-layer approach see <a href="../patterns_md.html#1-the-app-base-component-layer">Real-world patterns</a>.</p>
148
+ </div></div>
149
+
150
+ <div id="footer">
151
+ Generated on Mon May 18 13:55:33 2026 by
152
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
153
+ 0.9.34 (ruby-3.3.5).
154
+ </div>
155
+
156
+ </div>
157
+ </body>
158
+ </html>