Hot Glue Versions Save

Rapid scaffold builder for Turbo-Rails and Hotwire. Get the tutorial now at:

v0.5.23.1

8 months ago
  • You can now use the modify flag on enum type fields to display a partial with the same name of that enum type.

--modify=status{partials}

Here, status is an enum field on your table; you must use the exact string partials when using this feature.

You're telling Hot Glue to build scaffold that will display the status enum field as a partial.

It will look for a partial in the same build directory, whose name matches to the value of the enum. You will need to create a partial for each enum option that you have defined.

Remember when defining enums Rails will patch methods on your objects with the name of the enum types, so you must avoid namespace collisions with existing Ruby or Rails methods that are common to all objects -- like, for example, new.

  • Before this feature, enums always rendered like this on the show page: <%= domain.status %> (or, if you use custom labels:) <%= Domain.status_labels(domain.status)

  • After, you if you use the --modify flag and modify the enum to 'partials', your show output will render:

<%= render partial: thing.status, locals: {thing: thing} %>

(In this example Thing is the name of the model being built.)

Your form will also render the partial, but after the collection_select used to create the drop-down. (So it will render both the drop-down and the partial. This implementation has the drawback of no immediate switch between the partials when changing the drop-down, so it is not as responsive of an interaction design as it could be.)

Assuming your Thing enum is defined like so:

enum status: {abc: 'abc', dfg: 'dfg', hgk: 'hgk'}

You then would create three partials in the things directory. Make sure to create a partial for each defined enum, or else your app will crash when it tries to render a record with that enum.

_abc.html.erb
_dfg.html.erb
_hgk.html.erb

If your enum is on the show-only list, then the drop-down does not appear (but the partial is rendered).

Proof-of-concept can be found here: https://github.com/hot-glue-for-rails/HGEnumWithPartials1

Remember to see the section marked 'A Note About Enums' for more about working with Rails 7 enums.

Screenshot 2023-10-01 at 8 45 58 AM Screenshot 2023-10-01 at 8 45 53 AM hg-enums-with-partials

v0.5.22

8 months ago
  • adds back magic button tap-away params in the controller (in the update method)
  • changes creation of flash[:notice] (in update method`)
  • adds pundit authorization for edit action in the edit method itself
  • adds a crude show method that redirects to the edit (Hot Glue takes the opinionated stance that show routes should not really exist. This addition makes it so that when the user is on the show route and re-loads the browse window, they don't see a route error)
  • adds RuboCop detection; if you have RuboCop, the regen code at the top of the controller is excluded from the Layout/LineLength cop
  • fixes for specs

v0.5.21

8 months ago
  • Removes @ symbols using instance variables in _edit partials and in the enum syntax
  • fixes in system_spec.rb.erb
  • Adds flags --no-controller and --no-list
  • adds regen code to a file in the views folder REGENERATE.md if you have set --no-controller

v0.5.20

8 months ago

--pundit

If you enable Pundit, your controllers will look for a Policy that matches the name of the thing being built.

Realtime Field-level Access Hot Glue gives you automatic field level access control if you create *_able? methods for each field you'd like to control on your Pundit policy.

Take note this is not what Pundit recommends in their documentation for field-level access control. Instead, it has been implemented this way to provide field-by-field user feedback to the user shown in red just like Rails validation errors are currently shown. (Remember, we're talking about an access control failure, which may involve conditions that look like what you'd typically see in Rails validations).

You can refine on a field-by-field and role-by-role basis, which users have access to edit which fields on the Hot Glue layout. For everyone else, they see the field as viewable only.

A user inputting a field they don't have access to edit is only hypothetical for Hot Glue, because the interface correctly shows the field non-editable for them anyway. But, if the interface was edited or simply hacked (your web user can add hidden fields using the DevTools to try to set the values they don't have access to), the backend policy will prevent the hacking attempt by applying the access control in the update? method of the policy. You can set the object errors here when catching for access control errors, as you see in the example below.

The *_able? method should return true if the field can be edited and false if the field should appear as viewable only (non-editable). No distinction is made between the create/edit contexts. You may check if the record is new using new_record?. To remove the field completely, either remove it from your --include list or add it to your --exclude list, whichever you are using.

The *_able? method is used by Hot Glue only on the new and edit actions, but you must incorporate it into the policy's update? method as in the example, which will extend other operations since Hot Glue will use the policy to authorize the action Add one *_able? method to the policy for each field you want to allow field-level access control.

Replace * with the name of the field you want under access control. Remember to include _id for foreign keys. You do not need it for any field you don't want under access control.

When the method returns true, the field will be displayed to the user (and allowed) for editing. When the method returns false, the field will be displayed as read-only (viewable) to the user.

Important: These special fields determine only display behavior (new and edit), not create and update.

For create & update field-level access control, you must also implement the update? method on the Policy. Notice how in the example policy below, the update? method uses the name_able? method when it is checking if the name field can be updated, tying the feature together.

You can set Pundit to be enabled globally on the whole project for every build in config/hot_glue.yml (then you can leave off the --pundit flag from the scaffold command) :pundit_default: (all builds in that project will use Pundit)

Here's an example ThingPolicy that would allow editing the name field only if: • the current user is an admin • the sent_at date is nil (meaning it has not been sent yet)

For your policies, copy the initialize method of both the outer class (ThingPolicy) and the inner class (Scope) exactly as shown below.

If you argue with this implementation and think that there should be a way to make a field invisible based on access control — for example, if you have two different user contexts (roles) with different concerns and you want to use the same Hot Glue controller — instead you should simply make different Hot Glue controllers for the different purposes, hiding or showing the fields applicable to the users in their contexts. A singular application-wide policy is used to enforce consistency across the app, but each area of the app (namespaced Hot Glue controller) has a different user context interaction and, therefore, which fields to include or exclude get defined based on that.

class ThingPolicy < ApplicationPolicy
  def initialize(user, record)
    @user = user
    @record = record
  end
  
  def name_able?
    @record.sent_at.nil?
  end
  
  def update?
     if [email protected]_admin?
       return false
    elsif record.name_changed? && !name_able?
      record.errors.add(:name, "cannot be changed.")
      return false
    else
      return true
    end
  end
  
  class Scope < Scope
    attr_reader :user, :scope
    def initialize(user, scope)
      @user = user
      @scope = scope
    end
  end
end

Because Hot Glue detects the *_able? methods at build time, if you add them to your policy, you will have to rebuild your scaffold.

When mixing the show only, update show only, and Pundit features, notice that the show only and update show only will act to override whatever the policy might say, so fields specified in those settings will be shown as viewable (non-editable) even when the policy may allow it.

Remember, the show only list is specified using --show-only and the update show only list is specified using --update-show-only.

'Viewable' means it displays as view-only (not editable) even on the form. In this context, 'viewable' means 'read-only'. It does not mean 'visible'.

That's because when the field is not viewable, then it is editable or inputable. This may seem counter-intuitive for a standard interpretation of the word 'viewable,' but consider that Hot Glue has been carefully designed this way. If you do not want the field to appear at all, remove it using the exclude list or don't specify it in your include list.

If the field is being built, Hot Glue assumes your users want to see or edit it. Other special cases are beyond the scope of Hot Glue but can easily be added using direct customization of the code.

Without Pundit:

on new screen on edit screen
for a field on the show only list viewable viewable
for a field on the update show only list inputable viewable
for all other fields inputable inputable

With Pundit:

on new screen on edit screen
for a field on the show only list viewable viewable
for a field on the update show only list check policy viewable
for all other fields check policy check policy

v0.5.19

8 months ago

Given a table generated with this schema:

rails generate model Thing abc:boolean dfg:boolean hij:boolean 

• You can now use new flag --display-as to determine how the booleans will be displayed: checkbox, radio, or switch

rails generate hot_glue:scaffold Thing --include=abc,dfg,hij--god --display-as='abc{checkbox},dfg{radio},hij{switch}'

You may specify a default default_boolean_display in config/hot_glue.yml, like so:

:default_boolean_display: 'radio'

(The options are checkbox, radio, or switch.) If none is given and no default is specified, legacy display behavior will be used (radio buttons)

Screenshot 2023-08-22 at 7 40 44 PM

You still use the --modify flag to determine the truthy and falsy labels, which are also used as the truth and false when a boolean is displays as radio button, as shown in the dfg field above. (switches and checkboxes simply display with the field label and do not use the truthy and falsy labels)

hot-gluev0 5 19- fancy booleans

v0.5.18

8 months ago
  • there are three ways Hot Glue deals with Datetime fields:

  • (1) with current users who have timezone method (field or method)

  • (2) without current user timezone and no global timezone set for your app

  • (3) without current user timezone and global timezone set for your app

  • For #1, previously this method returned a time zone offset (integer). After v0.5.18, the preferred return value is a Timezone string, but legacy implementation returning offset values will continue to work. Your user objects should have a field called timezone which should be a string.

  • Note that daylight savings time is accounted for in this implementation.

  • For #2 (your user does not have a timezone field and you have not set the timezone globally), all datetimes will display in UTC timezone.

  • For #3 (your user does not have a timezone field but you have set the timezone globally), your datetimes will display in the Rails-specified timezone.

  • be sure to configure in config/application.rb this:

config.time_zone = 'Eastern Time (US & Canada)'

This should be your business's default timezone.

(#93) fixes variables be more clear if they are TimeZone objects (https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html) or are UTC offset (integers -/+ from UTC)

  • fixes spec assertions for DateTime and Time fields
  • removes randomness causing race conditions in the datetime object specs - fixes issue where setting bootstrap-column-width was not preferred if… (#88)
  • fixes flash notice output

v0.5.17

9 months ago

• Nav templates (_nav.html.erb) are now automatically appended to if they exist. Remember nav template live in the views folder at the root of the namespace, which is one folder up from whatever folder is being built. If a file exists _nav.html.erb, it will get appnded to with content like this:

<li class="nav-item">
    <%= link_to "Domains", domains_path, class: "nav-link #{'active' if nav == 'domains'}" %>
  </li>

This append to the _nav.html.erb template happens in addition to the partial itself being included from the layout. (Also only if it exists, so be sure create it before running the scaffold generators for the namespace. Of course, you only need to create it once for each namespace)

• To create a new _nav.html.erb template use

bin/rails generate hot_glue:nav_template --namespace=xyz

Here, you give only the namespace. It will create an empty nav template:

<ul class='nav nav-tabs'>
</ul>

• Fixes to specs for datetimes

• Fixes way the flash notices where created that violated frozen string literal

v0.5.16

9 months ago

--modify=field1{...},field2{...}

You can apply the modification to the viewable (non-edit) display of the field using the --modify switch.

The currency syntax is --modify=cost{$},price{$}

Here, the cost and price fields will be displayed as wrapped in number_to_currency() when displayed on the list view and when displayed as show-only.

You can also use a binary modifier, which can apply to booleans, datetimes, times, dates or anything else. When using the binary modify, a specific value is displayed if the field is truthy and another one is display if the field is falsy. You specify it using a pipe | character like so:

--modify=paid_at{paid|unpaid}

here, even though paid_at is a datetime field, it will display as-if it is a binary— showing either the truthy label or the falsy label depending on if paid_at is or is not null in the database. For all fields except booleans, this affects only the viewable output — what you see on the list page and on the edit page for show-only fields. For booleans, it affects those outputs as well as the normal edit output: The labels you specify are used as the labels for the radio buttons that the user can select.

You must separately specify these as show-only if you want them to be non-editable.

The available modifiers are:

modifier what it does can be used on
$ wraps output in number_to_currency() float, integer
truthy label|falsy label specify a binary switch with a pipe (|) character if the value is truthy, it will display as "truthy label" if the value is falsy, it will display as "falsy label" boolean, datetime, date, time

v0.5.15

9 months ago
  • When using big edit, updating a child will now re-render the parent EDIT record automatically.

For example rails generate hot_glue:scafold Invoice --big-edit rails generate hot_glue:scafold LineItem --nested=invioce

Whenever the line item is created, updated, or destroyed, the parent invoice record gets (edit action) re-rendered automatically. This happens for the big edit screen of the invoice.

  • Refactors fields into polymoric objects

  • Adds test coverage for Postgres Enums

  • Fixes tests on CI (and switches to CircleCI)

v0.5.14

1 year ago

After you upgrade to 0.5.14 from a prior version, please re-install the global flash notice template with

rails generate hot_glue:flash_notices_install

The newer template will work with old Hot Glue scaffold (generated prior to 0.5.14) and new scaffold moving forward. Old scaffold you have previously built should be unaffected, but new scaffold will only display errors correctly if you re-install the flash notice template using the line above. (If you fail to re-install the flash notice template scaffold built on or after this version will be missing detailed error message for the model on the create/update failure case)

If you miss this step, your old Hot Glue flash notices template will not show the model error messages (but will continue to show the global alert & notice messages)

Scaffold built after this release will no longer contain an _errors file previously copied into every build folder.

  • The destroy action on controllers now produces an "alert" message for successful deletion.

If you like Hot Glue, please consider purchasing my course here.