9. Create Forms

September 2015 · 4 minute read

Database Table: In my app/db/migrate it shows what information can be set in the income table. It also shows that all fields must be filled in for the form to be submitted.

Views:

First, I’m going to create an _incomes_form.html.erb partial is a data entry form which will allow me to input data regarding income information and then save it to the main page. It will also redirect back to an updated index page once data entry is complete.

This partial needs to be called from the new.html.erb file I created in my last tutorial and can be done so with the following line. This line needs to be in <%brackets%> because it is a ruby call, in an html file.

We can test this out by writing something in the new partial and refreshing the localhost3000/income/new path

new

<%= render 'incomes/incomes_form' %>

For data entry to occur, I need to code some forms. I’m going to use a bootstrap form with fields for data entry. I am going to code each form field to access a specific field in my income table. This is a loop which will iterate through all the field’s specified within the income table:

Controller: In my income/controller.rb I now need to define “new” so that the compiler knows that this is going to be a new row in my income table (in the posgreSQL db). New is defined as follows:

<%= form_for [@income] do |f| %>
  <div class="field">
    <%= f.label :wages %><br /> <%= f.number_field :wages %>
  </div>
<% end %>

ERROR: I receive a series of errors which points out that I need to be careful how I name my files and because of pluralisation I need to rename my views and controller file. After renaming them all correctly

app/controllers/incomes_controller.rb

app/models/income.rb

app/views/incomes

Errors then continue to give directions as to where those changes need to be updated throughout the application

Create: Now that I have the _income_form.html partial rendering for @income, it can be tested by typing a number in the form and hitting enter. Naturally, I get an error because I have not declared the “create” action in my controller.rb

This block will call the income_params and store the data I’ve just entered in the :wages field

def create
  @income = Income.new(income_params)
    respond_to do |format|	  
      if @income.save    
      format.html { redirect_to incomes_path}
    end
  end
end

I receive a new error which tells me that I need to provide information in all of the table fields in order for this to be valid. This can be seen in the Income Migration, where it has been specified that all fields are compulsory.

The extra fields just need to be included in the views/_incomes_form.html.erb

<%= form_for [@incomes] do |f| %>
  <div class="field">
    <%= f.label :wages %><br /> <%= f.number_field :wages %>
  </div>
<% end %>

After refreshing the localhost:3000/incomes/new page, the missing fields will appear. Now when you hit enter nothing happens (or does it?) – the error is gone though

Now I want this new data to be updated in a table when I return to my index page after saving. I can draw up a table in the app/views/index.html.erb which will access the new data stored.

This is my new income partial

<%= form_for [@income] do |f| %>

  <div class="field">
    <%= f.label :wages %><br /> <%= f.number_field :wages %>
  </div>

  <div>
    <%= f.label :other_income %><br /> <%= f.number_field :other_income %>
  </div>

  <div>
    <%= f.label :income_total %><br /> <%= f.number_field :income_total %>
  </div>

<% end %>

Next, the new form needs a “submit” button to actually save the data

<div class="actions">
  <%= f.submit %>
</div>

And that’s when you’ll get a new error which cannot redirect to nil and prompt the need for an ‘update’ action in the incomes_controller.rb

The redirection path in the income_controller.rb simply needs to be updated as we do not have the need for a ‘show’ file

format.html { redirect_to incomes_path}

The new link now works. You can also see that the save action from earlier had done something and multiple rows have now been created.

The other thing we can do at this point, having decided there will be no need for a ‘show’ path (which is automatically generated when resources are created) in the design, I can simply exclude it in the routes.rb

Rails.application.routes.draw do
  resources :incomes, except: [:show]

  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

To prove this has worked, exit the rails server and run

$ rake routes

There is no longer an income#show route available.

Refresh the localhost and everything else still works just fine. Optimisation as you go keeps your files clean and tidy - its easier to read later on, when it gets really complicated.

*Ref: