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.
In this lesson, we will cover the following key concepts:
- Creating a form for adding new
ToDo
items. - Handling form submissions to save the new
ToDo
items. - Redirecting users to the details page of the newly created
ToDo
.
Let's start with setting up the controller. Open your todos_controller.rb
and update it as follows:
Ruby1class 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
, anddescription
set tonil
or empty strings). This is necessary to instantiate the form fields when creating a newToDo
item. -
create
Action: This method is responsible for handling the submission of thenew
form. It calls a service (TodoService.create
) that processestodo_params
to create a newToDo
item. After successfully creating a new item, it redirects the user to the details page of the newToDo
by usingredirect_to todo_path(todo[:id])
. -
show
Action: This method retrieves an existingToDo
item using a service (TodoService.find
) and the passedparams[:id]
. It assigns the foundToDo
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.
To support the creation of new ToDo
items, we'll simulate storage using an in-memory list. Below is the modified TodoService
code:
Ruby1class 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 storeToDo
items in memory. This approach allows us to manageToDo
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 newToDo
based on the previous item's ID, constructs thetodo
item with the provided parameters, and appends it to@todos
. -
get_all
Method: This method returns all storedToDo
items from the in-memory list. -
get_by_id
Method: This method retrieves a specificToDo
item based on itsid
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.
Next, we will set up the form view in app/views/todos/new.html.erb
to collect user input.
ERB1<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 totodos_path
, ensuring the data is sent to thecreate
action ofTodosController
. Thelocal: 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 fortitle
anddescription
.form.label
generates a label tag for each field, whileform.text_field
andform.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 newToDo
item.
By adding this form, you're allowing users to create and submit new ToDo
items with a title and description.
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!