plutonium 0.5.0

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 (346) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.ruby-version +1 -0
  4. data/.standard.yml +4 -0
  5. data/.vscode/extensions.json +15 -0
  6. data/.vscode/launch.json +7 -0
  7. data/.vscode/settings.json +35 -0
  8. data/CHANGELOG.md +5 -0
  9. data/LICENSE.txt +21 -0
  10. data/README copy.md +84 -0
  11. data/README.md +67 -0
  12. data/Rakefile +8 -0
  13. data/app/views/layouts/resource.html.erb +43 -0
  14. data/app/views/resource/_color_modes.html.erb +55 -0
  15. data/app/views/resource/_details.html.erb +6 -0
  16. data/app/views/resource/_empty_card.html.erb +12 -0
  17. data/app/views/resource/_flash.html.erb +9 -0
  18. data/app/views/resource/_form.html.erb +32 -0
  19. data/app/views/resource/_header.html.erb +8 -0
  20. data/app/views/resource/_interactive_resource_action_form.html.erb +67 -0
  21. data/app/views/resource/_messages.html.erb +1 -0
  22. data/app/views/resource/_metric_card.html.erb +16 -0
  23. data/app/views/resource/_nav_user.html.erb +4 -0
  24. data/app/views/resource/_pagination.html.erb +6 -0
  25. data/app/views/resource/_pagy_pagination.html.erb +15 -0
  26. data/app/views/resource/_resource.html.erb +1 -0
  27. data/app/views/resource/_resource.rabl +5 -0
  28. data/app/views/resource/_sidebar.html.erb +11 -0
  29. data/app/views/resource/_sidebar_menu.html.erb +1 -0
  30. data/app/views/resource/_tab_menu.html.erb +13 -0
  31. data/app/views/resource/_table.html.erb +78 -0
  32. data/app/views/resource/_table_actions.html.erb +15 -0
  33. data/app/views/resource/_toast.html.erb +26 -0
  34. data/app/views/resource/_toolbar.html.erb +22 -0
  35. data/app/views/resource/_toolbar_actions.html.erb +16 -0
  36. data/app/views/resource/_toolbar_breadcrumbs.html.erb +32 -0
  37. data/app/views/resource/_toolbar_search_input.erb +27 -0
  38. data/app/views/resource/edit.html.erb +10 -0
  39. data/app/views/resource/errors.rabl +3 -0
  40. data/app/views/resource/index.html.erb +19 -0
  41. data/app/views/resource/index.rabl +3 -0
  42. data/app/views/resource/interactive_resource_collection_action.html.erb +11 -0
  43. data/app/views/resource/interactive_resource_record_action.html.erb +11 -0
  44. data/app/views/resource/interactive_resource_recordless_action.html.erb +11 -0
  45. data/app/views/resource/new.html.erb +11 -0
  46. data/app/views/resource/readme.md +16 -0
  47. data/app/views/resource/show.html.erb +14 -0
  48. data/app/views/resource/show.rabl +3 -0
  49. data/brakeman.ignore +51 -0
  50. data/lib/active_model/validations/array_validator.rb +74 -0
  51. data/lib/active_model/validations/attached_validator.rb +17 -0
  52. data/lib/active_model/validations/url_validator.rb +51 -0
  53. data/lib/generators/pu/core/install/install_generator.rb +43 -0
  54. data/lib/generators/pu/core/install/templates/.keep +0 -0
  55. data/lib/generators/pu/core/install/templates/app/controllers/resource_controller.rb.tt +2 -0
  56. data/lib/generators/pu/core/install/templates/app/interactions/resource_interaction.rb.tt +2 -0
  57. data/lib/generators/pu/core/install/templates/app/models/resource_record.rb.tt +5 -0
  58. data/lib/generators/pu/core/install/templates/app/policies/resource_policy.rb.tt +2 -0
  59. data/lib/generators/pu/core/install/templates/app/presenters/resource_presenter.rb.tt +2 -0
  60. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +2 -0
  61. data/lib/generators/pu/core/install/templates/config/packages.rb +3 -0
  62. data/lib/generators/pu/gem/pagy/pagy_generator.rb +25 -0
  63. data/lib/generators/pu/gem/pagy/templates/.keep +0 -0
  64. data/lib/generators/pu/gem/pagy/templates/config/initializers/pagy.rb +4 -0
  65. data/lib/generators/pu/gem/rabl/rabl_generator.rb +25 -0
  66. data/lib/generators/pu/gem/rabl/templates/.keep +0 -0
  67. data/lib/generators/pu/gem/rabl/templates/config/initializers/rabl.rb +60 -0
  68. data/lib/generators/pu/gem/simple_form/simple_form_generator.rb +25 -0
  69. data/lib/generators/pu/gem/simple_form/templates/.keep +0 -0
  70. data/lib/generators/pu/gen/pug/pug_generator.rb +43 -0
  71. data/lib/generators/pu/gen/pug/templates/pug.rb.tt +23 -0
  72. data/lib/generators/pu/pkg/app/app_generator.rb +60 -0
  73. data/lib/generators/pu/pkg/app/templates/app/controllers/resource_controller.rb.tt +26 -0
  74. data/lib/generators/pu/pkg/app/templates/app/interactions/resource_interaction.rb.tt +4 -0
  75. data/lib/generators/pu/pkg/app/templates/app/policies/resource_policy.rb.tt +4 -0
  76. data/lib/generators/pu/pkg/app/templates/app/presenters/resource_presenter.rb.tt +4 -0
  77. data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +17 -0
  78. data/lib/generators/pu/pkg/app/templates/lib/engine.rb.tt +14 -0
  79. data/lib/generators/pu/pkg/feature/feature_generator.rb +44 -0
  80. data/lib/generators/pu/pkg/feature/templates/.keep +0 -0
  81. data/lib/generators/pu/pkg/feature/templates/app/controllers/resource_controller.rb.tt +7 -0
  82. data/lib/generators/pu/pkg/feature/templates/app/interactions/resource_interaction.rb.tt +4 -0
  83. data/lib/generators/pu/pkg/feature/templates/app/models/resource_record.rb.tt +5 -0
  84. data/lib/generators/pu/pkg/feature/templates/app/policies/resource_policy.rb.tt +4 -0
  85. data/lib/generators/pu/pkg/feature/templates/app/presenters/resource_presenter.rb.tt +4 -0
  86. data/lib/generators/pu/pkg/feature/templates/lib/engine.rb.tt +8 -0
  87. data/lib/generators/pu/resource/conn/conn_generator.rb +54 -0
  88. data/lib/generators/pu/resource/conn/templates/.keep +0 -0
  89. data/lib/generators/pu/resource/conn/templates/app/controllers/resource_controller.rb.tt +3 -0
  90. data/lib/generators/pu/resource/conn/templates/app/policies/resource_policy.rb.tt +3 -0
  91. data/lib/generators/pu/resource/conn/templates/app/presenters/resource_presenter.rb.tt +3 -0
  92. data/lib/generators/pu/resource/model/USAGE +113 -0
  93. data/lib/generators/pu/resource/model/model_generator.rb +163 -0
  94. data/lib/generators/pu/resource/model/templates/controller.rb.tt +5 -0
  95. data/lib/generators/pu/resource/model/templates/create_table_migration.rb.tt +26 -0
  96. data/lib/generators/pu/resource/model/templates/model.rb.tt +53 -0
  97. data/lib/generators/pu/resource/model/templates/module.rb.tt +7 -0
  98. data/lib/generators/pu/resource/model/templates/policy.rb.tt +4 -0
  99. data/lib/generators/pu/resource/model/templates/presenter.rb.tt +4 -0
  100. data/lib/generators/pu/resource/scaffold/scaffold_generator.rb +219 -0
  101. data/lib/generators/pu/resource/scaffold/templates/app/controllers/admin_resources/resource_controller.rb.tt +7 -0
  102. data/lib/generators/pu/resource/scaffold/templates/app/controllers/entity_resources/resource_controller.rb.tt +7 -0
  103. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/admin/resource_policy.rb.tt +22 -0
  104. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/entity/resource_policy.rb.tt +22 -0
  105. data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/resource_policy.rb.tt +13 -0
  106. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/admin_presenter.rb.tt +7 -0
  107. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/entity_presenter.rb.tt +7 -0
  108. data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/presenter.rb.tt +23 -0
  109. data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.html.erb.tt +3 -0
  110. data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.rabl +7 -0
  111. data/lib/generators/pu/rodauth/account_generator.rb +120 -0
  112. data/lib/generators/pu/rodauth/concerns/account_selector.rb +22 -0
  113. data/lib/generators/pu/rodauth/concerns/configuration.rb +211 -0
  114. data/lib/generators/pu/rodauth/concerns/feature_selector.rb +125 -0
  115. data/lib/generators/pu/rodauth/install_generator.rb +69 -0
  116. data/lib/generators/pu/rodauth/migration/active_record/account_expiration.erb +8 -0
  117. data/lib/generators/pu/rodauth/migration/active_record/active_sessions.erb +7 -0
  118. data/lib/generators/pu/rodauth/migration/active_record/audit_logging.erb +16 -0
  119. data/lib/generators/pu/rodauth/migration/active_record/base.erb +22 -0
  120. data/lib/generators/pu/rodauth/migration/active_record/disallow_password_reuse.erb +5 -0
  121. data/lib/generators/pu/rodauth/migration/active_record/email_auth.erb +8 -0
  122. data/lib/generators/pu/rodauth/migration/active_record/jwt_refresh.erb +7 -0
  123. data/lib/generators/pu/rodauth/migration/active_record/lockout.erb +13 -0
  124. data/lib/generators/pu/rodauth/migration/active_record/otp.erb +8 -0
  125. data/lib/generators/pu/rodauth/migration/active_record/password_expiration.erb +6 -0
  126. data/lib/generators/pu/rodauth/migration/active_record/recovery_codes.erb +6 -0
  127. data/lib/generators/pu/rodauth/migration/active_record/remember.erb +7 -0
  128. data/lib/generators/pu/rodauth/migration/active_record/reset_password.erb +8 -0
  129. data/lib/generators/pu/rodauth/migration/active_record/separate_passwords.erb +5 -0
  130. data/lib/generators/pu/rodauth/migration/active_record/single_session.erb +6 -0
  131. data/lib/generators/pu/rodauth/migration/active_record/sms_codes.erb +9 -0
  132. data/lib/generators/pu/rodauth/migration/active_record/verify_account.erb +8 -0
  133. data/lib/generators/pu/rodauth/migration/active_record/verify_login_change.erb +8 -0
  134. data/lib/generators/pu/rodauth/migration/active_record/webauthn.erb +13 -0
  135. data/lib/generators/pu/rodauth/migration/sequel/account_expiration.erb +7 -0
  136. data/lib/generators/pu/rodauth/migration/sequel/active_sessions.erb +8 -0
  137. data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +17 -0
  138. data/lib/generators/pu/rodauth/migration/sequel/base.erb +25 -0
  139. data/lib/generators/pu/rodauth/migration/sequel/disallow_password_reuse.erb +6 -0
  140. data/lib/generators/pu/rodauth/migration/sequel/email_auth.erb +7 -0
  141. data/lib/generators/pu/rodauth/migration/sequel/jwt_refresh.erb +8 -0
  142. data/lib/generators/pu/rodauth/migration/sequel/lockout.erb +11 -0
  143. data/lib/generators/pu/rodauth/migration/sequel/otp.erb +7 -0
  144. data/lib/generators/pu/rodauth/migration/sequel/password_expiration.erb +5 -0
  145. data/lib/generators/pu/rodauth/migration/sequel/recovery_codes.erb +6 -0
  146. data/lib/generators/pu/rodauth/migration/sequel/remember.erb +6 -0
  147. data/lib/generators/pu/rodauth/migration/sequel/reset_password.erb +7 -0
  148. data/lib/generators/pu/rodauth/migration/sequel/separate_passwords.erb +6 -0
  149. data/lib/generators/pu/rodauth/migration/sequel/single_session.erb +5 -0
  150. data/lib/generators/pu/rodauth/migration/sequel/sms_codes.erb +8 -0
  151. data/lib/generators/pu/rodauth/migration/sequel/verify_account.erb +7 -0
  152. data/lib/generators/pu/rodauth/migration/sequel/verify_login_change.erb +7 -0
  153. data/lib/generators/pu/rodauth/migration/sequel/webauthn.erb +13 -0
  154. data/lib/generators/pu/rodauth/migration_generator.rb +190 -0
  155. data/lib/generators/pu/rodauth/templates/INSTRUCTIONS +52 -0
  156. data/lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt +6 -0
  157. data/lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt +3 -0
  158. data/lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt +4 -0
  159. data/lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +62 -0
  160. data/lib/generators/pu/rodauth/templates/app/misc/account_rodauth_plugin.rb.tt +255 -0
  161. data/lib/generators/pu/rodauth/templates/app/misc/rodauth_app.rb.tt +24 -0
  162. data/lib/generators/pu/rodauth/templates/app/misc/rodauth_plugin.rb.tt +234 -0
  163. data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +40 -0
  164. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +7 -0
  165. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form.html.erb +26 -0
  166. data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +9 -0
  167. data/lib/generators/pu/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +6 -0
  168. data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_login.html.erb +27 -0
  169. data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_password.html.erb +27 -0
  170. data/lib/generators/pu/rodauth/templates/app/views/rodauth/close_account.html.erb +13 -0
  171. data/lib/generators/pu/rodauth/templates/app/views/rodauth/confirm_password.html.erb +11 -0
  172. data/lib/generators/pu/rodauth/templates/app/views/rodauth/create_account.html.erb +35 -0
  173. data/lib/generators/pu/rodauth/templates/app/views/rodauth/email_auth.html.erb +5 -0
  174. data/lib/generators/pu/rodauth/templates/app/views/rodauth/login.html.erb +4 -0
  175. data/lib/generators/pu/rodauth/templates/app/views/rodauth/logout.html.erb +14 -0
  176. data/lib/generators/pu/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +3 -0
  177. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_auth.html.erb +15 -0
  178. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_disable.html.erb +13 -0
  179. data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_setup.html.erb +41 -0
  180. data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +11 -0
  181. data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +13 -0
  182. data/lib/generators/pu/rodauth/templates/app/views/rodauth/remember.html.erb +22 -0
  183. data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password.html.erb +19 -0
  184. data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +17 -0
  185. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_auth.html.erb +15 -0
  186. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +15 -0
  187. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_disable.html.erb +13 -0
  188. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_request.html.erb +5 -0
  189. data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_setup.html.erb +23 -0
  190. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_email_auth_request_form.html.erb +5 -0
  191. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +24 -0
  192. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form_footer.html.erb +7 -0
  193. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/add_recovery_codes.html.erb +16 -0
  194. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_login.html.erb +25 -0
  195. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_password.html.erb +25 -0
  196. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/close_account.html.erb +11 -0
  197. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/confirm_password.html.erb +19 -0
  198. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/create_account.html.erb +33 -0
  199. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/email_auth.html.erb +3 -0
  200. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +5 -0
  201. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/logout.html.erb +10 -0
  202. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +5 -0
  203. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_auth.html.erb +9 -0
  204. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_disable.html.erb +11 -0
  205. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_setup.html.erb +32 -0
  206. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_auth.html.erb +9 -0
  207. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_codes.html.erb +11 -0
  208. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/remember.html.erb +18 -0
  209. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password.html.erb +17 -0
  210. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password_request.html.erb +17 -0
  211. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_auth.html.erb +9 -0
  212. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_confirm.html.erb +9 -0
  213. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_disable.html.erb +11 -0
  214. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_request.html.erb +3 -0
  215. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_setup.html.erb +17 -0
  216. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_auth.html.erb +5 -0
  217. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_disable.html.erb +11 -0
  218. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_manage.html.erb +26 -0
  219. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account.html.erb +15 -0
  220. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account_request.html.erb +9 -0
  221. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account.html.erb +19 -0
  222. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account_resend.html.erb +17 -0
  223. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_login_change.html.erb +3 -0
  224. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_auth.html.erb +13 -0
  225. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
  226. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_remove.html.erb +21 -0
  227. data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_setup.html.erb +21 -0
  228. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +5 -0
  229. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +13 -0
  230. data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +22 -0
  231. data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account.html.erb +15 -0
  232. data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +9 -0
  233. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account.html.erb +21 -0
  234. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +17 -0
  235. data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +5 -0
  236. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +15 -0
  237. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
  238. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +23 -0
  239. data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +23 -0
  240. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb +5 -0
  241. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/password_changed.text.erb +2 -0
  242. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb +5 -0
  243. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password_notify.text.erb +2 -0
  244. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +5 -0
  245. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb +4 -0
  246. data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +10 -0
  247. data/lib/generators/pu/rodauth/templates/config/initializers/rodauth.rb.tt +3 -0
  248. data/lib/generators/pu/rodauth/templates/db/migrate/create_rodauth.rb.tt +13 -0
  249. data/lib/generators/pu/rodauth/views_generator.rb +125 -0
  250. data/lib/plutonium/auth/public_access.rb +17 -0
  251. data/lib/plutonium/auth/rodauth.rb +35 -0
  252. data/lib/plutonium/auth.rb +12 -0
  253. data/lib/plutonium/config.rb +11 -0
  254. data/lib/plutonium/core/.DS_Store +0 -0
  255. data/lib/plutonium/core/action.rb +46 -0
  256. data/lib/plutonium/core/actions/basic_action.rb +16 -0
  257. data/lib/plutonium/core/actions/collection.rb +33 -0
  258. data/lib/plutonium/core/actions/destroy_action.rb +21 -0
  259. data/lib/plutonium/core/actions/edit_action.rb +19 -0
  260. data/lib/plutonium/core/actions/interactive_action.rb +64 -0
  261. data/lib/plutonium/core/actions/new_action.rb +18 -0
  262. data/lib/plutonium/core/actions/show_action.rb +17 -0
  263. data/lib/plutonium/core/actions.rb +17 -0
  264. data/lib/plutonium/core/app_controller.rb +121 -0
  265. data/lib/plutonium/core/autodiscovery/discoverer.rb +15 -0
  266. data/lib/plutonium/core/autodiscovery/input_discoverer.rb +33 -0
  267. data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +33 -0
  268. data/lib/plutonium/core/autodiscovery.rb +13 -0
  269. data/lib/plutonium/core/controllers/authorizable.rb +56 -0
  270. data/lib/plutonium/core/controllers/bootable.rb +44 -0
  271. data/lib/plutonium/core/controllers/crud_actions.rb +128 -0
  272. data/lib/plutonium/core/controllers/entity_scoping.rb +69 -0
  273. data/lib/plutonium/core/controllers/interactive_actions.rb +210 -0
  274. data/lib/plutonium/core/controllers/presentable.rb +59 -0
  275. data/lib/plutonium/core/controllers.rb +16 -0
  276. data/lib/plutonium/core/definers/action_definer.rb +25 -0
  277. data/lib/plutonium/core/definers/field_definer.rb +19 -0
  278. data/lib/plutonium/core/definers/input_definer.rb +37 -0
  279. data/lib/plutonium/core/definers/renderer_definer.rb +35 -0
  280. data/lib/plutonium/core/definers.rb +14 -0
  281. data/lib/plutonium/core/fields/inputs/association_input.rb +26 -0
  282. data/lib/plutonium/core/fields/inputs/basic_input.rb +42 -0
  283. data/lib/plutonium/core/fields/inputs/belongs_to_input.rb +15 -0
  284. data/lib/plutonium/core/fields/inputs/factory.rb +58 -0
  285. data/lib/plutonium/core/fields/inputs/has_many_input.rb +15 -0
  286. data/lib/plutonium/core/fields/inputs/noop_input.rb +19 -0
  287. data/lib/plutonium/core/fields/inputs.rb +18 -0
  288. data/lib/plutonium/core/fields/renderers/association_renderer.rb +25 -0
  289. data/lib/plutonium/core/fields/renderers/basic_renderer.rb +27 -0
  290. data/lib/plutonium/core/fields/renderers/factory.rb +52 -0
  291. data/lib/plutonium/core/fields/renderers.rb +15 -0
  292. data/lib/plutonium/core/fields.rb +12 -0
  293. data/lib/plutonium/core/ui/collection.rb +14 -0
  294. data/lib/plutonium/core/ui/detail.rb +11 -0
  295. data/lib/plutonium/core/ui/form.rb +11 -0
  296. data/lib/plutonium/core/ui.rb +13 -0
  297. data/lib/plutonium/core.rb +16 -0
  298. data/lib/plutonium/helpers/action_buttons_helper.rb +32 -0
  299. data/lib/plutonium/helpers/application_helper.rb +22 -0
  300. data/lib/plutonium/helpers/attachment_helper.rb +62 -0
  301. data/lib/plutonium/helpers/content_helper.rb +66 -0
  302. data/lib/plutonium/helpers/display_helper.rb +83 -0
  303. data/lib/plutonium/helpers/form_helper.rb +24 -0
  304. data/lib/plutonium/helpers/menu_helper.rb +69 -0
  305. data/lib/plutonium/helpers/pagination_helper.rb +9 -0
  306. data/lib/plutonium/helpers/turbo_helper.rb +13 -0
  307. data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +9 -0
  308. data/lib/plutonium/helpers.rb +31 -0
  309. data/lib/plutonium/initializers/TODO +2 -0
  310. data/lib/plutonium/initializers/pagy.rb +5 -0
  311. data/lib/plutonium/initializers/patches.rb +2 -0
  312. data/lib/plutonium/initializers/rabl.rb +60 -0
  313. data/lib/plutonium/initializers/simple_form.rb +405 -0
  314. data/lib/plutonium/lib/after_commit.rb +34 -0
  315. data/lib/plutonium/lib/bit_flags.rb +36 -0
  316. data/lib/plutonium/packaging/app.rb +125 -0
  317. data/lib/plutonium/packaging/feature.rb +18 -0
  318. data/lib/plutonium/packaging/package.rb +22 -0
  319. data/lib/plutonium/packaging.rb +9 -0
  320. data/lib/plutonium/policy/initializer.rb +22 -0
  321. data/lib/plutonium/policy/scope.rb +19 -0
  322. data/lib/plutonium/policy.rb +8 -0
  323. data/lib/plutonium/preserved__/field.rb +65 -0
  324. data/lib/plutonium/preserved__/input.rb +93 -0
  325. data/lib/plutonium/reactor/core.rb +61 -0
  326. data/lib/plutonium/reactor/resource_context.rb +15 -0
  327. data/lib/plutonium/reactor/resource_controller.rb +108 -0
  328. data/lib/plutonium/reactor/resource_interaction.rb +8 -0
  329. data/lib/plutonium/reactor/resource_policy.rb +105 -0
  330. data/lib/plutonium/reactor/resource_presenter.rb +42 -0
  331. data/lib/plutonium/reactor/resource_record.rb +123 -0
  332. data/lib/plutonium/reactor.rb +13 -0
  333. data/lib/plutonium/refinements/parameter_refinements.rb +26 -0
  334. data/lib/plutonium/simple_form_components/attachment_component.rb +77 -0
  335. data/lib/plutonium/simple_form_components/input_group_component.rb +14 -0
  336. data/lib/plutonium/version.rb +3 -0
  337. data/lib/plutonium.rb +31 -0
  338. data/plutonium.gemspec +47 -0
  339. data/public/.keep +0 -0
  340. data/public/plutonium-assets/application.css +24280 -0
  341. data/public/plutonium-assets/application.js +31420 -0
  342. data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
  343. data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
  344. data/public/plutonium-assets/logo.png +0 -0
  345. data/sig/plutonium.rbs +4 -0
  346. metadata +519 -0
@@ -0,0 +1,4 @@
1
+ require "pagy/extras/bootstrap"
2
+ require "pagy/extras/overflow"
3
+ require "pagy/extras/trim"
4
+ require "pagy/extras/headers"
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class RablGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Install Rabl"
13
+
14
+ def start
15
+ Bundler.with_unbundled_env do
16
+ run "bundle add rabl"
17
+ end
18
+
19
+ directory "config"
20
+ rescue => e
21
+ exception "#{self.class} failed:", e
22
+ end
23
+ end
24
+ end
25
+ end
File without changes
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # https://github.com/nesquena/rabl#configuration
4
+
5
+ Rabl.configure do |config|
6
+ config.cache_sources = !Rails.env.development? # Defaults to false
7
+ config.raise_on_missing_attribute = !Rails.env.production? # Defaults to false
8
+
9
+ # config.cache_all_output = false
10
+ # config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache
11
+ # config.perform_caching = false
12
+ # config.escape_all_output = false
13
+ # config.json_engine = nil # Class with #dump class method (defaults JSON)
14
+ # config.msgpack_engine = nil # Defaults to ::MessagePack
15
+ # config.bson_engine = nil # Defaults to ::BSON
16
+ # config.plist_engine = nil # Defaults to ::Plist::Emit
17
+ # config.include_json_root = true
18
+ # config.include_msgpack_root = true
19
+ # config.include_bson_root = true
20
+ # config.include_plist_root = true
21
+ # config.include_xml_root = false
22
+ # config.include_child_root = true
23
+ # config.enable_json_callbacks = false
24
+ # config.xml_options = { :dasherize => true, :skip_types => false }
25
+ # config.view_paths = []
26
+ # config.replace_nil_values_with_empty_strings = true # Defaults to false
27
+ # config.replace_empty_string_values_with_nil_values = true # Defaults to false
28
+ # config.exclude_nil_values = true # Defaults to false
29
+ # config.exclude_empty_values_in_collections = true # Defaults to false
30
+ # config.camelize_keys = :upper # Defaults to false
31
+ end
32
+
33
+ # Monkey Patch Rabl source lookup to make it compatible with Rails view lookup
34
+ module Rabl
35
+ module Sources
36
+ private
37
+
38
+ # Returns the rabl template path for Rails
39
+ def fetch_rails_source(file, _options = {})
40
+ # use Rails template resolution mechanism if possible (find_template)
41
+ source_format = request_format if defined?(request_format)
42
+
43
+ lookup_proc = lambda do |partial|
44
+ context_scope.lookup_context.find(file, context_scope.lookup_context.prefixes, partial, [],
45
+ {formats: [source_format]})
46
+ end
47
+ template = begin
48
+ lookup_proc.call(false)
49
+ rescue
50
+ nil
51
+ end
52
+ template ||= begin
53
+ lookup_proc.call(true)
54
+ rescue
55
+ nil
56
+ end
57
+ template&.identifier
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "plutonium_generators"
4
+
5
+ module Pu
6
+ module Gem
7
+ class SimpleFormGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Install SimpleForm"
13
+
14
+ def start
15
+ Bundler.with_unbundled_env do
16
+ run "bundle add simple_form"
17
+ end
18
+
19
+ directory "config"
20
+ rescue => e
21
+ exception "#{self.class} failed:", e
22
+ end
23
+ end
24
+ end
25
+ end
File without changes
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ return if PlutoniumGenerators.rails?
4
+
5
+ module Pu
6
+ module Gen
7
+ class PugGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ desc "Create a new pug"
11
+
12
+ argument :name
13
+ class_option :desc, type: :string, desc: "Description of your pug"
14
+
15
+ def start
16
+ template "pug.rb.tt", "lib/generators/pu/#{pug_path}/#{pug_class.underscore}.rb"
17
+ create_file "lib/generators/pu/#{pug_path}/templates/.keep"
18
+ end
19
+
20
+ def rubocop
21
+ run "standardrb --fix"
22
+ end
23
+
24
+ protected
25
+
26
+ def pug_name
27
+ name.split(":").map(&:camelize).join("::")
28
+ end
29
+
30
+ def pug_path
31
+ pug_name.underscore
32
+ end
33
+
34
+ def pug_module
35
+ pug_name.deconstantize
36
+ end
37
+
38
+ def pug_class
39
+ "#{pug_name.demodulize}Generator"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../../../plutonium_generators', __dir__)
4
+
5
+ module Pu
6
+ module <%= pug_module %>
7
+ class <%= pug_class %> < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path('templates', __dir__)
11
+
12
+ desc '<%= options[:desc] || 'TODO: add description' %>'
13
+
14
+ argument :name
15
+
16
+ def start
17
+ raise NotImplementedError, "<%= pug_name %>"
18
+ rescue StandardError => e
19
+ exception "#{self.class} failed:", e
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "plutonium_generators"
4
+
5
+ module Pu
6
+ module Pkg
7
+ class AppGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Create a plutonium app package"
13
+
14
+ argument :name
15
+
16
+ def start
17
+ validate_package_name package_name
18
+
19
+ if defined?(RodauthApp) && (rodauths = RodauthApp.opts[:rodauths].keys).present?
20
+ rodauth_account = prompt.select("Select rodauth account to authenticate with:", rodauths + [:none])
21
+ @rodauth_account = rodauth_account unless rodauth_account == :none
22
+ elsif prompt.yes?("Do you want to grant public access?")
23
+ @public_access = true
24
+ else
25
+ @bring_your_own_auth = true
26
+ end
27
+
28
+ template "lib/engine.rb", "packages/#{package_namespace}/lib/engine.rb"
29
+ template "config/routes.rb", "packages/#{package_namespace}/config/routes.rb"
30
+
31
+ %w[controllers interactions policies presenters].each do |dir|
32
+ directory "app/#{dir}", "packages/#{package_namespace}/app/#{dir}/#{package_namespace}"
33
+ end
34
+ create_file "packages/#{package_namespace}/app/views/#{package_namespace}/.keep"
35
+ rescue => e
36
+ exception "#{self.class} failed:", e
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :rodauth_account
42
+
43
+ def package_name
44
+ name.classify + "App"
45
+ end
46
+
47
+ def package_namespace
48
+ package_name.underscore
49
+ end
50
+
51
+ def package_type
52
+ "Packaging::App"
53
+ end
54
+
55
+ def public_access? = @public_access
56
+
57
+ def bring_your_own_auth? = @bring_your_own_auth
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,26 @@
1
+ module <%= package_name %>
2
+ module ResourceController
3
+ extend ActiveSupport::Concern
4
+ include Plutonium::Core::AppController
5
+ <%- if rodauth_account.present? -%>
6
+ include Plutonium::Auth.rodauth(:<%= rodauth_account %>)
7
+ <%- elsif public_access? -%>
8
+ include Plutonium::Auth::PublicAccess
9
+ <%- end -%>
10
+ # add concerns above.
11
+
12
+ included do
13
+ boot <%= package_name %>
14
+ <%- if bring_your_own_auth? -%>
15
+
16
+ helper_method :current_user
17
+ <%- end -%>
18
+ end
19
+ <%- if bring_your_own_auth? -%>
20
+
21
+ def current_user
22
+ raise NotImplementedError, "#{self.class}#current_user must return a non nil value"
23
+ end
24
+ <%- end -%>
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ module ResourceInteraction
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ module ResourcePolicy
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ module ResourcePresenter
3
+ end
4
+ end
@@ -0,0 +1,17 @@
1
+ # <%= package_name %>::Engine.routes.draw do
2
+ # # add custom app routes here
3
+ # end
4
+
5
+ # draw routes for registered resources
6
+ <%= package_name %>::Engine.draw_resource_routes
7
+
8
+ # mount our app
9
+ Rails.application.routes.draw do
10
+ <%- if rodauth_account.present? -%>
11
+ constraints Rodauth::Rails.authenticate(:<%= rodauth_account %>) do
12
+ mount <%= package_name %>::Engine, at: "/<%= name.underscore %>"
13
+ end
14
+ <%- else -%>
15
+ mount <%= package_name %>::Engine, at: "/<%= name.underscore %>"
16
+ <%- end -%>
17
+ end
@@ -0,0 +1,14 @@
1
+ module <%= package_name %>
2
+ class Engine < Rails::Engine
3
+ include Plutonium::<%= package_type %>
4
+ # add concerns above.
5
+
6
+ config.after_initialize do
7
+ initialize_register!
8
+
9
+ # add directives above.
10
+
11
+ # register resources above.
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "plutonium_generators"
4
+
5
+ module Pu
6
+ module Pkg
7
+ class FeatureGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Create a plutonium feature package"
13
+
14
+ argument :name
15
+
16
+ def start
17
+ validate_package_name package_name
18
+
19
+ template "lib/engine.rb", "packages/#{package_namespace}/lib/engine.rb"
20
+
21
+ %w[controllers interactions models policies presenters].each do |dir|
22
+ directory "app/#{dir}", "packages/#{package_namespace}/app/#{dir}/#{package_namespace}"
23
+ end
24
+ create_file "packages/#{package_namespace}/app/views/#{package_namespace}/.keep"
25
+ rescue => e
26
+ exception "#{self.class} failed:", e
27
+ end
28
+
29
+ private
30
+
31
+ def package_name
32
+ name.classify
33
+ end
34
+
35
+ def package_namespace
36
+ package_name.underscore
37
+ end
38
+
39
+ def package_type
40
+ "Packaging::Feature"
41
+ end
42
+ end
43
+ end
44
+ end
File without changes
@@ -0,0 +1,7 @@
1
+ module <%= package_name %>
2
+ class ResourceController < ::ResourceController
3
+ # add concerns above.
4
+
5
+ boot <%= package_name %>
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ class ResourceInteraction < ::ResourceInteraction
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module <%= package_name %>
2
+ class ResourceRecord < ::ResourceRecord
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ class ResourcePolicy < ::ResourcePolicy
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module <%= package_name %>
2
+ class ResourcePresenter < ::ResourcePresenter
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module <%= package_name %>
2
+ class Engine < Rails::Engine
3
+ include Plutonium::<%= package_type %>
4
+ # add concerns above.
5
+
6
+ # add directives above
7
+ end
8
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "plutonium_generators"
4
+
5
+ module Pu
6
+ module Resource
7
+ class ConnGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Create a connection between a resource and an app"
13
+
14
+ # argument :name
15
+
16
+ def start
17
+ source_feature = select_feature
18
+ source_module = (source_feature == "main_app") ? "ResourceRecord" : "#{source_feature.classify}::ResourceRecord"
19
+
20
+ Rails.application.eager_load!
21
+ available_resources = source_module.constantize.descendants.map(&:to_s)
22
+ selected_resources = prompt.multi_select("Select resources", available_resources)
23
+
24
+ @app_namespace = select_app.classify
25
+
26
+ selected_resources.each do |resource|
27
+ @resource_class = resource
28
+
29
+ template "app/controllers/resource_controller.rb", "packages/#{package_namespace}/app/controllers/#{package_namespace}/#{resource.pluralize.underscore}_controller.rb"
30
+ template "app/policies/resource_policy.rb", "packages/#{package_namespace}/app/policies/#{package_namespace}/#{resource.underscore}_policy.rb"
31
+ template "app/presenters/resource_presenter.rb", "packages/#{package_namespace}/app/presenters/#{package_namespace}/#{resource.underscore}_presenter.rb"
32
+
33
+ insert_into_file "packages/#{package_namespace}/lib/engine.rb",
34
+ indent("register_resource ::#{resource}\n", 6),
35
+ before: /.*# register resources above.*/
36
+ end
37
+ rescue => e
38
+ exception "#{self.class} failed:", e
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :app_namespace, :resource_class
44
+
45
+ def package_namespace
46
+ app_namespace.underscore
47
+ end
48
+
49
+ def resource_namespace
50
+ app_namespace.underscore
51
+ end
52
+ end
53
+ end
54
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ class <%= app_namespace %>::<%= resource_class.pluralize %>Controller < ::<%= resource_class.pluralize %>Controller
2
+ include <%= app_namespace %>::ResourceController
3
+ end
@@ -0,0 +1,3 @@
1
+ class <%= app_namespace %>::<%= resource_class %>Policy < ::<%= resource_class %>Policy
2
+ include <%= app_namespace %>::ResourcePolicy
3
+ end
@@ -0,0 +1,3 @@
1
+ class <%= app_namespace %>::<%= resource_class %>Presenter < ::<%= resource_class %>Presenter
2
+ include <%= app_namespace %>::ResourcePresenter
3
+ end
@@ -0,0 +1,113 @@
1
+ Description:
2
+ Generates a new model. Pass the model name, either CamelCased or
3
+ under_scored, and an optional list of attribute pairs as arguments.
4
+
5
+ Attribute pairs are field:type arguments specifying the
6
+ model's attributes. Timestamps are added by default, so you don't have to
7
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
8
+
9
+ As a special case, specifying 'password:digest' will generate a
10
+ password_digest field of string type, and configure your generated model and
11
+ tests for use with Active Model has_secure_password (assuming the default ORM
12
+ and test framework are being used).
13
+
14
+ You don't have to think up every attribute up front, but it helps to
15
+ sketch out a few so you can start working with the model immediately.
16
+
17
+ This generator invokes your configured ORM and test framework, which
18
+ defaults to Active Record and TestUnit.
19
+
20
+ Finally, if --parent option is given, it's used as superclass of the
21
+ created model. This allows you create Single Table Inheritance models.
22
+
23
+ If you pass a namespaced model name (e.g. admin/account or Admin::Account)
24
+ then the generator will create a module with a table_name_prefix method
25
+ to prefix the model's table name with the module name (e.g. admin_accounts)
26
+
27
+ Available field types:
28
+
29
+ Just after the field name you can specify a type like text or boolean.
30
+ It will generate the column with the associated SQL type. For instance:
31
+
32
+ `bin/rails generate model post title:string body:text`
33
+
34
+ will generate a title column with a varchar type and a body column with a text
35
+ type. If no type is specified the string type will be used by default.
36
+ You can use the following types:
37
+
38
+ integer
39
+ primary_key
40
+ decimal
41
+ float
42
+ boolean
43
+ binary
44
+ string
45
+ text
46
+ date
47
+ time
48
+ datetime
49
+
50
+ You can also consider `references` as a kind of type. For instance, if you run:
51
+
52
+ `bin/rails generate model photo title:string album:references`
53
+
54
+ It will generate an `album_id` column. You should generate these kinds of fields when
55
+ you will use a `belongs_to` association, for instance. `references` also supports
56
+ polymorphism, you can enable polymorphism like this:
57
+
58
+ `bin/rails generate model product supplier:references{polymorphic}`
59
+
60
+ For integer, string, text and binary fields, an integer in curly braces will
61
+ be set as the limit:
62
+
63
+ `bin/rails generate model user pseudo:string{30}`
64
+
65
+ For decimal, two integers separated by a comma in curly braces will be used
66
+ for precision and scale:
67
+
68
+ `bin/rails generate model product 'price:decimal{10,2}'`
69
+
70
+ You can add a `:uniq` or `:index` suffix for unique or standard indexes
71
+ respectively:
72
+
73
+ `bin/rails generate model user pseudo:string:uniq`
74
+ `bin/rails generate model user pseudo:string:index`
75
+
76
+ You can combine any single curly brace option with the index options:
77
+
78
+ `bin/rails generate model user username:string{30}:uniq`
79
+ `bin/rails generate model product supplier:references{polymorphic}:index`
80
+
81
+ If you require a `password_digest` string column for use with
82
+ has_secure_password, you can specify `password:digest`:
83
+
84
+ `bin/rails generate model user password:digest`
85
+
86
+ If you require a `token` string column for use with
87
+ has_secure_token, you can specify `auth_token:token`:
88
+
89
+ `bin/rails generate model user auth_token:token`
90
+
91
+ Examples:
92
+ `bin/rails generate model account`
93
+
94
+ For Active Record and TestUnit it creates:
95
+
96
+ Model: app/models/account.rb
97
+ Test: test/models/account_test.rb
98
+ Fixtures: test/fixtures/accounts.yml
99
+ Migration: db/migrate/XXX_create_accounts.rb
100
+
101
+ `bin/rails generate model post title:string body:text published:boolean`
102
+
103
+ Creates a Post model with a string title, text body, and published flag.
104
+
105
+ `bin/rails generate model admin/account`
106
+
107
+ For Active Record and TestUnit it creates:
108
+
109
+ Module: app/models/admin.rb
110
+ Model: app/models/admin/account.rb
111
+ Test: test/models/admin/account_test.rb
112
+ Fixtures: test/fixtures/admin/accounts.yml
113
+ Migration: db/migrate/XXX_create_admin_accounts.rb