Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand on form pattern documentation validation, error handling #11611

Merged
merged 2 commits into from
Dec 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 56 additions & 7 deletions docs/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,68 @@ Forms should have a `#submit` method that returns a `FormResponse`.
- `extra:` is, by convention, a method called `extra_analytics_attributes` that
returns a Hash

```ruby
def submit
FormResponse.new(
success: valid?,
errors: errors,
extra: extra_analytics_attributes,
)
By including `ActiveModel::Model`, you can use any of [Rails' built-in model validation helpers](https://guides.rubyonrails.org/active_record_validations.html#validation-helpers)
or define [custom validation logic](https://guides.rubyonrails.org/active_record_validations.html#custom-methods).
Regardless how you validate, you should use human-readable error messages and associate the error to
the specific form parameter field that it affects, if the form is responsible for validating input
from a page.

```rb
class NewEmailForm
include ActiveModel::Model
include ActionView::Helpers::TranslationHelper

validates_presence_of :email, { message: proc { I18n.t('errors.email.blank')} }
validate :validate_banned_email

def submit(email:)
@email = email

FormResponse.new(success: valid?, errors:, extra: extra_analytics_attributes)
end

def validate_banned_email
return if !BannedEmail.find_by(email: @email)
errors.add(:email, :banned, message: t('errors.email.banned'))
end

# ...
end
```

For sensitive properties, or results that are not meant to be logged, add
properties to the Form object that get written during `#submit`

### Form Error Handling

If form validation is unsuccessful, you should inform the user what needs to be done to correct the
issue by one or both of the following:

- Flash message
- Inline field errors

For convenience, a `FormResponse` object includes a `first_error_message` method which can be used
if you want to display a single error message, such as in a flash banner.

```rb
result = @form.submit(**params)
if result.success?
# ...
else
flash.now[:error] = result.first_error_message
render :new
end
```

In the view, a [SimpleForm](https://github.com/heartcombo/simple_form) form can be bound to a form
object. By doing so, each error will automatically be shown with the corresponding page input.

```erb
<%= simple_form_for @form, url: emails_path do |f| %>
<%= render ValidatedFieldComponent.new(form: f, name: :email) %>
<% end >
```

### Analytics

Analytics events are appended to `log/events.log` and contain information both common information as
Expand Down