Create Read Update Delete

Journal 03

Next step on the journey is learning how to implement some fairly rudimentary, essential functions. Create, Read, Update, Delete or in acronym form: CRUD.

I can already create entries, and show them on screen; edit and delete them via Terminal; but it would be so much neater, nicer and easier to be able to do it on the page itself. I’m so keen to edit my initial posts that were gibberish, frankly!

It also means I’ll soon have some forms to do some styling on! πŸ˜€

Resources

Rails conveniently maps these main CRUD items in just one nice command: resources. I changed the config file to include:

resources :articles

This nicely maps out all of the actions I’ll need to use – such as create, edit and destroy.

Create

Ok, finally time to add in a form I can create new posts with! Fantastic!

In the controller, define new and create.

def new
    @article = Article.new
  end

  def create
    @article = Article.new(title: "...", subtitle: "...", body: "...")

Then finish this off with a little redirect to go back to the list of posts.

 if @article.save
      redirect_to @article
    else
      render :new
    end
  end

The if / else means this will only occur if it saves (on the create action). Otherwise, it will stay where it is on the ‘new’ page.

Form time!

Firstly, create a new view which will encapsulate the form. Having a form builder makes it really simple to implement with just a few lines of code.

<%= form_with model: @article do |form| %>
  <div>
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div>
    <%= form.label :subtitle %>
    <%= form.text_area :subtitle %>
  </div>

  <div>
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>

  <div>
    <%= form.submit %>
  </div>

Labels, text fields and text areas. I always like that detail of text areas that let you resize the box to fit the amount of text you would like to write. Great!

We then did a simple, yet clever security catch – by making sure the form can only accept the parameters we allow.

Of course with forms, come error messages! (Again, looking forward to styling these soon!)

I immediately started typing out a useful error message, related to the issue of an empty field.

It’s so frustrating when error messages are overlooked and lead to a difficult user experience – I had this trying to create an account the other day; I couldn’t see any missed fields and it wouldn’t accept the form – or help me to see what I had missed. I gave up. It’s a big error with real consequences and it isn’t hard to fix at all!

Dennis was quick to point out I didn’t need to add a message though – Rails is smart enough to provide a meaningful error message already – and with relatively extensive language support. Brilliant!

For each form field add the following to the view corresponding to the form. It’s important to use full_messages_for in order to get those nice, user-friendly messages.

@article.errors.full_messages_for(:title).each do |message| %>
      <div><%= message %></div>

I also added validations – but let’s not go into the detail of that.

Read

We covered this when we started to show content πŸ™‚

Update

I’ve been waiting patiently for this one!

First we have to request a form to edit the data – make the changes – and then save it. (Again bringing in validation and redirects).

Edit and update handle this one. Also defined in the controller, similarly to new and create.

We can reuse the view for ‘form’ we created earlier – now pulling it out to be a partial. This becomes a reusable part and is indicated by an underscore at the start of the file. It becomes: _form.html.erb

We then render this in our ‘new’ view.

<%= render "form", article: @article %>

A new view is needed for edit – and it renders the above, too. Add a ‘link_to’ on the show articles view and that will work to link the user to be able to edit the entry. Easy!

 <li><%= link_to "Edit", edit_article_path(@article) %>

Delete-Destroy

Destroy always sounds so dramatic! I guess it is, when it really does destroy it!

This follows a pretty similar pattern to the others – this time we can add in a confirmation prompt from the browser. (Another thing to later style, if possible?)

Again, this pops up in the view (after we’ve defined destroy in the controller with a redirect back to the articles page)

In the show view:

</li>
  <li><%= link_to "Destroy", article_path(@article),
                  method: :delete,
                  data: { confirm: "Are you sure?" } %>

It sits nicely next to ‘edit’.

There is a better way to delete things though – a softer delete that can be recovered. It involves a bit of filtering of what is shown. Perhaps at a later date…

So that’s it! CRUD implemented. I did the same for a comments feature – so you will see that pop up now too. πŸ™‚