Mordtech's Blog

General Technology Blog

Ruby on Rails Tutorial – Task Management App

In this third post of the Ruby on Rails tutorial. We’ll start building out the real application. In this post, we’ll be using the Rails scaffold generator, and a few Zurb building blocks. We’ll also be creating a few custom functions and routes.

Configuring our first object

Our first object will include the following fields – Name, status, order, due date, location, description. Ruby on Rails provides a built in generator that will build the model (think standard database object), the views (these index, show, new, update) and the controller (the code to create, update, delete, show, and index). The index shows all of the data in the database for that specific model, the remaining are individual to a specific row in the database. As we start building out our app, we’ll modify the index, and the default forms.

There are two schools of thought when teaching Rails, the first is to use the scaffold and modify it to fit your needs. The second, is to build each piece up individually as you need it. This tutorial falls into the first school. Let the built in generator build what out the basics, and add or delete as needed. The only time, we will deviate from this, if we do not much of the needed code. An audit trigger for example.

So, to build our first object, we’ll run the following command in the terminal

Rails g scaffold task name:string status:string order:integer duedate:datetime location:string description:text

Ok, lets go over what this does. First, the Rails tells the operating system what application you want to run. Next is the g, this is short for Generate. This tells rails what process you want it to run. Next, is scaffold, Rails generate a scaffold for me. The fourth work task is the is the object name. key point to remember here, always lower case and always singular. The Ruby on Rails “Configuration of code” model will make it capitilized where needed and plural where needed. Next are the fields and the type. Examples of data types are

  • string
  • text
  • integer
  • datetime
  • boolean

UntitledSo, after running the command, you’ll see the output of the code at the right. But, if you were to try and open the tasks page in your app, you would receive an error. this is because the rails generator will build the rails objects, (model, views and controllers), it will not build the actual database objects. It will however, build a migration file that will be used to build the database files. there are many reasons for this, but one main reason, is that it allows us to modify the migration file to make slight changes. example, we can add indexes to the migration file that will be built when we run the next command: rake db:migrate   As you can see, the application that is called, is different than before. Here, we are running the rake application. The second portion, is db:migrate. We are telling rails to run all of the new migration files since the last rake db:migrate. We could also reset the database db:reset, create the db if needed db:create, etc… So, when you check the page, you might get the following error. This is due to loading the Zurb Foundation gem, and not restarting the rails server. If you do, restart your rails server , and reload the page.  Untitled

Now add the following to the end of your URL:

/tasks

And press enter, you’ll see the following page. If you click the “New Task” link, you can enter tasks.

Untitled

Untitled

Success, we have have a functional Task management app.

Setting the default home page

Now lets make the app a bit more appealing. First, we don’t want our users entering the tasks each time, they open our app, so lets configure our route file to  default to  the tasks index page. Open the routes file in the config folder and add the following line:

root ‘tasks#index’

Now if you go back to the browser and go http://localhost:3000 you’ll see the index page for tasks and not the ruby on rails default page.

Configure the responsive navbar with links to index and new tasks

We’ll be using the Zurb building block for a reponsive nav bar at http://foundation.zurb.com/docs/components/topbar.html

Copy the html and post in the application.html.erb, save the file and reload the page in the browser. Now, lets modify the code to make it more personal

Change <a href=”#”>My Site</a>

To <%= link_to “Task Manager“, root_path %>

This is the first bit of Ruby, this creates a dynamic html link to the object defined as the root path that we configured earlier, currently, it is the tasks#index. Its been awhile, so lets do a commit here.

Run git commit -am “added task list and navbar”

Update task list index to have three columns

Now open the tasks index page and copy in the following code:

<div class=”row”>

<div class=“medium-4 columns”>

</div>

<div class=“medium-4 columns”>

</div>

<div class=“medium-4 columns”>

</div>

</div>

And cut and past the table into the the first section:

<div class=”medium-4 columns”>

<Table>

</Table>

</div>

Reload your page and see how it looks. Now lets clean up the table a bit, lets get rid of a few columns and the extra actions at the end. Change the table info to the following:

<table>
<thead>
<tr>
<th>Name</th>
<th>Process</th>
</tr>
</thead>

<tbody>
<% @tasks.each do |task| %>
<tr>
<td><%= link_to task.name, task %></td>
<td>Process</td>
</tr>
<% end %>
</tbody>
</table>

One thing that we did was to change the link_to to the task.name instead of having it as a show at the end. We also added a column for process. This will hold the button to move the task between states. Now, copy the same table into the other two sections. We’ll modify them in a few minutes. Nows is  a good time for a commit

Run git commit -am “setup sections”

Create three filters for the index page (new, in process, complete)

Now we create the filters. First, open the tasks controller and modify the index section to the following:

@newTasks = Task.where(:status => “New”)

@inprocessTasks = Task.where(:status => “In Process”)

@blockTasks = Task.where(:status => “Blocked”)

In the tasks index page set the first @tasks.each to @ newTasks.each. Set the second to @ inprocessTasks.each and the third to @blockTasks.each, and change the table column name to “New Tasks”, “In Process Tasks”, “Blocked Tasks”. Time for another commit.

Set the active button to create a new task

In the application.html.erb replace the left section hyperlink with the following <%= link_to “New Task”, new_task_path %>.

Now remove the new task link from the index page and commit the changes.

The table should be structured to look like a post

OK, this section will have numerous changes. We’ll be using foundations building blocks here, and the one we’ll be using is Info Card With Corner Lables found at http://zurb.com/building-blocks/info-card-with-corner-lables

first, we’ll replace the body of the each table with the following html from the building block

<div class=”callout-card primary radius”>

<div class=”card-label”>

<div class=”label-text”>

Win!

</div>

</div>

<div class=”callout-card-content”>

<h3 class=”lead”> Mad Max: Fury Road</h3>

<p>In a post-apocalyptic world, in which people fight to the death, Max teams up with a mysterious woman, Furiousa, to try and survive.</p>

</div>

</div>

Next replace <h3 class=”lead”> Mad Max: Fury Road</h3> with   <h4 class=”lead”><%= link_to task.name, task %></h4>.

Now open the page, and you’ll notice that not much has changed. Next we need to modify our CSS files. Open foundations_and_overrides and paste in the css from the building place page. Place the code near the bottom just above the @import ‘foundation’; text. Next remove the <th>Process</th> and <td>Process</td> from each of the three tables. Finally,  remove the following from each section.

<div class=”label-text”>

Process

</Div>

Reload your page and now you should notice the difference.

Each post should have a button to move to the next process

For the buttons, we’ll be using the default Zurb settings. We’ll have one button for each task in the new column  called process. We’ll have two buttons for each task in the in process column, one called complete, one called block.  There are few things that need to be performed to get the buttons to work correctly.

First, we need to create three functions in the tasks controller to the processing

The three functions are nearly identical, only the name an the status data changes

They will look like this

def processTask

respond_to do |format|

if @task_processing.update_attribute(:status, “In Process”)

format.html { redirect_to tasks_path, notice: ‘Task was successfully updated.’ }

format.json { render :show, status: :ok, location: @task_processing }

else

format.html { redirect_to tasks_path, notice: ‘Task was processed.’ }

format.json { render json: @task_processing.errors, status: :unprocessable_entity }

end

end

End

To make them different, change the name processTask to completeTask for the second and blockTask for the third. Next change :status, “In Process” to :status, “Complete” for the completeTask and :status, “Blocked” for the blockTask.

Second, we need to create a function to pull the task Id. To do this, we need enter code in the private section of the tasks controller. In the private section, enter the following

def get_task_id

@task_processing = Task.find(params[:task_id])

end

Third, we need to set a before action to run the pull taskID when one of the three functions are called. Copy this code near the top of the tasks controller under the existing similar line:

before_action :get_task_id, only: [ :processTask, :blockTask, :completeTask]

Save the file, and we are done here.

Next,  we need to edit the task routes to call the new function. Change the resources :tasks to:

resources :tasks do

  put :processTask

  put :blockTask

  put :completeTask

end

Now save the file.

Add the buttons to the page

We’ll have 4 total buttons, 2 in the in-process column, and one each in the new and the blocked columns. First, we need to copy the following code under under the appropriate <h4 class=“Lead” line

New column =

<div style=”float:left;”>

<%= button_to(“Process”, task_processTask_path(task), :method => :put, class: “tiny round button”) %>

</div>

In Process Column =

<div style=”float:left;”>

<%= button_to(“Block”, task_blockTask_path(task), :method => :put, class: “tiny round button”) %>

<%= button_to(“Complete”, task_completeTask_path(task), :method => :put, class: “tiny round button”) %>

</div>

and in the blocked Column =

<div style=”float:left;”>

<%= button_to(“Process”, task_processTask_path(task), :method => :put, class: “tiny round button”) %>

</div>

Lets do the final commit for this post, and reload the page and you should be able to click the buttons and move your tasks through their workflow.

There is still a lot to do, clean up the new and edit form, add authentication, add groups, etc.. This is a good place to stop. The next post, will be about setting up bitbucket, where you’ll can see the code, that we’ve built so far.

Mordtech's Blog © 2015
%d bloggers like this: