Essential Guide 4: Forms & Actions (Create, Update, Delete)
Demo: Matestack Demo Github Repo: Matestack Demo Application
Welcome to the fourth part of our tutorial about building a web application with matestack.
Introduction
In the previous guide, we added index and show pages for the person model. In this part, we will implement the create, update and delete part of our CRUD application. For this we will introduce the matestack forms
.
In this guide, we will
add a new page and action action to create new persons
add an edit page and action to modify existing persons
add an delete action to delete existing persons
introduce the concept of matestack forms
introduce the concept of matestack actions
Prerequisites
We expect you to have successfully finished the previous guide.
Updating the person model
All persons should have a first name, last name and a role. Therefore we add validations to our person model for these three attributes in person.rb
.
We only check for presence of this three attributes.
Preparing routes & controller
In your config/routes.rb
, change
to
in order to let rails generate all CRUD routes for persons.
Then, in the persons_controller.rb
, update the contents like this:
What's going on there? We've added render
-calls for two new matestack pages (new, edit) and controller actions for create, update and destroy. To keep the code clean, we have extracted some functionality into a before_action
and added the person_params
method to extract person relevant params from all params in rails safe params manner.
Nothing extraordinary, but definitely stepping things up a bit!
Adding the new and edit pages with forms
Create a new page in app/matestack/demo/pages/persons/new.rb
and add the following content:
What's going on here? Let's break it down:
Within our response method we have at first a transition to the person index page. After that comes h2 tag as a headline stating 'Create a new person'. Nothing new so long. Afterwards comes an unfamiliar call of form
.
Let's take a closer look. Like in Rails with form_for
you can create a form in matestack with form
. It takes a hash as first argument for configuration. In this case we defined new_person_form_config
to return the config hash for our form. In the config hash you can set the http request method, a path, success and failure configs and a for key, which will be explained soon. This form gets submitted as a POST request to the persons_path
.
The for
key let's us define for what this form is. In this case we pass a empty model to the form component, which will therefore submit the form inputs wrapped by the model name following the Rails behavior and conventions.
The 'success' key let's us define a behavior when the form was submitted successful, which means the server returned a status code of 2XX. In this case we tell the form that if successful it should follow the transition path we return in our controller action. So a page transition will happen to the detail page of our newly created model. We could also configure a failure behavior by specifying the failure
key.
Inside our form component we have calls to normal html components like label, br, button
which render the corresponding html tag and we have calls for form inputs and a form submit. Let's take a closer look at the form_input
call. A form input at least requires a key and a type. The type can be any html input type possible. The key defines the input name as which it will get submitted. If the model specified by the for
key in the form config responds to the key the input will be prefilled with the value the model returns. form_radio, form_select, form_checkbox
helpers can take an array or hash in the options
key. They render for example a radio button for each option in the array or hash. In case of an array the label and value are the same for each radio button, in case of a hash the keys are used as labels and the values as values. To enable the user to submit the form, we added a button to click. This button needs to be wrapped inside a form_submit
call, which will take care of triggering the form submit if the contents inside the given block is clicked.
To learn more, check out the complete API documentation for the form
component.
Take a moment to familiarize yourself with everything going on and then go ahead and create another page in app/matestack/demo/pages/persons/edit.rb
, featuring similar content:
Again, we're using a form within the response
method and define its behaviour in the person_edit_form_config
. Since this time, an existing person is looked up in the database, the form gets initialized with his/her data as described above.
Updating the index page
Within the response
block on the Index page (app/matestack/demo/pages/persons/index.rb
), add the following line:
As you might have guessed, this takes us to the New page and you can create a new person there.
Further introduction: Forms
During this article, you've got a general idea of how matestack forms handle data input. But since this is only an introductory guide, we can't cover all the possible use cases and functionality in here.
Let's do a quick recap: The form
component can be used like other components we have seen before, but requires a hash as parameter for configuration. Within the hash, various configurations like HTTP method, submission path, payload and handling of success/failure responses can be set.
Beyond that, here's some suggestions of what you could try to add in the future:
uploading files
handling failure
different input types like email, password, textfield, range or dropdown
re-rendering parts of a page instead of doing a page transition
using other Ruby objects than ActiveRecord collections
fetching data from and sending data to third party APIs
To learn more, check out the complete API documentation for the form
component.
Adding a delete button for persons
We want to add the ability to delete persons. For that we add a delete button to the persons show page, which will destroy the person model when it was clicked. To achieve this we will use matestacks action
component.
Update your show page in app/matestack/demo/pages/persons/show.rb
to look like this:
As you see we wrap our delete button inside an action
component. Like the form
component, an action
component also takes a hash as first parameter for configuration. An action component triggers a asynchronous request when someone clicks on the wrapped content. The request target and http method are again configured in the hash. In this case when the action component is clicked it will send an DELETE request to /persons/:id
. For a successful request we configured our action
component to follow the redirect specified by the delete action. With the confirm
keyword we can configure that when the button is clicked a confirm dialog pops up and needs to be confirmed before the request is send.
Further introduction: Actions
As we've seen with the delete button, matestack
actions are a convenient way to trigger HTTP requests without having to write a lot of code.
Let's do a quick recap: Similar to the form
, an action
component requires a hash as parameter for configuration and wraps other content, for example a button. This content is then clickable and triggers whatever HTTP request is specified in the configuration.
Beyond that, here's some suggestions of what you could try to add in the future:
sending an advanced payload with the HTTP request
re-rendering parts of a page on successful request
To learn more, check out the complete API documentation for the action
component.
Local testing
Run rails s
and head over to localhost:3000 to test the changes! You should be able to create new persons as well as edit and delete existing ones!
Saving the status quo
As usual, we want to commit the progress to Git. In the repo root, run
Recap & outlook
By now, we have already implemented the complete CRUD (Create-Read-Update-Delete) functionality around the person model. Neat!
We got a brief introduction of the form
and action
components and know how to use them.
But there's still more guides coming - so what's left? In the upcoming chapters, we will dive deeper into some matestack
concepts to further enhance both user experience and developer happiness!
Take a well deserved rest and make sure to come back to the next part of this series, introducing the powerful toggle component
.
Last updated