Lesson 2
Setting Up Creation Query - Create with ToDo Item Form
Introduction to Creating ToDo Items

Welcome back! So far, we've learned how to retrieve ToDo items using GET queries. Now, it's time to make our application more interactive by allowing users to create new ToDo items. This lesson will focus on setting up the creation queries and building a form for users to input their ToDo items.

Creating ToDo items is a fundamental feature for our application. Imagine an app where you can see tasks but can't add new ones — it wouldn't be very useful! By the end of this lesson, you'll have significantly enhanced your app's functionality by enabling users to add new tasks.

Key Concepts

In this lesson, we will cover the following key concepts:

  1. Creating a form for adding new ToDo items.
  2. Handling form submissions to save the new ToDo items.
  3. Redirecting users to the details page of the newly created ToDo.
Setting Up the Controller

Let's start with setting up the controller. Open your todos_controller.rb and update it as follows:

Ruby
1class TodosController < ApplicationController 2 def new 3 @todo = { id: nil, title: '', description: '' } 4 end 5 6 def create 7 todo = TodoService.create(todo_params) 8 redirect_to todo_path(todo[:id]) 9 end 10 11 def show 12 @todo = TodoService.find(params[:id]) 13 end 14 15 private 16 17 def todo_params 18 params.require(:todo).permit(:title, :description) 19 end 20end

Code Explanation

  • new Action: This method initializes a new @todo object with default values (id, title, and description set to nil or empty strings). This is necessary to instantiate the form fields when creating a new ToDo item.

  • create Action: This method is responsible for handling the submission of the new form. It calls a service (TodoService.create) that processes todo_params to create a new ToDo item. After successfully creating a new item, it redirects the user to the details page of the new ToDo by using redirect_to todo_path(todo[:id]).

  • show Action: This method retrieves an existing ToDo item using a service (TodoService.find) and the passed params[:id]. It assigns the found ToDo to @todo for display purposes.

  • todo_params Method: This private method specifies and sanitizes the parameters (:title and :description) required from the form, preventing illegal data from being processed.

Modifying the Service

To support the creation of new ToDo items, we'll simulate storage using an in-memory list. Below is the modified TodoService code:

Ruby
1class TodoService 2 def self.create(todo_params) 3 @todos ||= [] 4 # Generate a new ID based on the last ToDo item's ID or start from 1 5 todo = { id: (@todos.last&.fetch(:id) || 0) + 1, **todo_params.symbolize_keys } 6 # Add the new ToDo item to the list 7 @todos.push(todo) 8 # Return the newly created ToDo item 9 todo 10 end 11 12 def self.get_all 13 # Return all ToDo items 14 @todos 15 end 16 17 def self.get_by_id(id) 18 # Find a ToDo item by its ID 19 @todos.find { |todo| todo[:id] == id.to_i } 20 end 21end

Code Explanation

  • In-Memory List: We're using an instance variable @todos to store ToDo items in memory. This approach allows us to manage ToDo items during the runtime of the application.

  • create Method: This method initializes @todos as an empty array if it's not already. It generates a unique ID for the new ToDo based on the previous item's ID, constructs the todo item with the provided parameters, and appends it to @todos.

  • get_all Method: This method returns all stored ToDo items from the in-memory list.

  • get_by_id Method: This method retrieves a specific ToDo item based on its id by searching through the @todos list.

Using an in-memory list is a straightforward way to handle ToDo items without complex storage solutions, perfect for simple applications and learning purposes.

Building the Form

Next, we will set up the form view in app/views/todos/new.html.erb to collect user input.

ERB
1<h1>Create a New Todo</h1> 2<%= form_with scope: :todo, url: todos_path, local: true do |form| %> 3 <div> 4 <%= form.label :title %> 5 <%= form.text_field :title %> 6 </div> 7 <div> 8 <%= form.label :description %> 9 <%= form.text_area :description %> 10 </div> 11 <div> 12 <%= form.submit "Create" %> 13 </div> 14<% end %>

Code Explanation

  • form_with Method: This helper builds a form scoped to :todo. It sets the form’s submission URL to todos_path, ensuring the data is sent to the create action of TodosController. The local: true option makes sure that the form submits the data using a regular HTTP request, not AJAX.

  • form.label and Field Methods: These are used to generate input elements for title and description. form.label generates a label tag for each field, while form.text_field and form.text_area create the input boxes for users to type in the title and description, respectively.

  • form.submit Method: This generates a submit button with the text "Create," allowing users to submit the form and create a new ToDo item.

By adding this form, you're allowing users to create and submit new ToDo items with a title and description.

Why It Matters

Creating new ToDo items is a critical feature for any task management application. It empowers users to manage their tasks dynamically, making the app far more useful. By understanding how to create new entries, you're adding a layer of functionality that is essential for interactive applications.

When users can easily add new tasks, your application becomes more than just a static list of predefined items. It becomes a tool that adapts to the users' needs. This capability boosts user engagement and makes your app practical for real-world use.

With excitement in the air, let's dive into the practice section and see this feature come to life!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.