Implementing File Upload Functionality in the ToDo App

Overview of File Uploading

Congratulations on progressing this far in building your ToDo App! Up until now, you have learned how to fetch, create, update, and delete ToDo items, significantly enhancing the functionality of your application. You’ve equipped users to manage their tasks dynamically. In this lesson, we will take another substantial step by implementing the functionality to upload files. This feature will allow users to associate documents or images with their ToDo items, providing an even richer user experience.

What You'll Learn

In this lesson, you will learn how to:

  • Implement a file upload endpoint in your Rails application.
  • Utilize Ruby on Rails' capabilities to handle file storage and management alongside your ToDo items.

Imagine needing a receipt, image, or any document associated with a task — file uploads make this possible. Here's a snippet showing the key components you will implement:

def upload
  if request.post?
    uploaded_file = params[:file]
    uploads_dir = Rails.root.join('public', 'uploads')

    # Create the uploads directory if it doesn't exist
    FileUtils.mkdir_p(uploads_dir) unless Dir.exist?(uploads_dir)

    filepath = uploads_dir.join(uploaded_file.original_filename)
    File.open(filepath, 'wb') do |file|
      file.write(uploaded_file.read)
    end

    todo = TodoService.add_file(params[:id], uploaded_file.original_filename)
    redirect_to todo_path(todo[:id])
  else
    set_todo
  end
end

In this segment, we define an upload method. It checks if a file is sent via a POST request and writes the file to a directory using File.open. After storing the file, it updates the ToDo item with the filename, enhancing the task details. Note that we do not need to call File.close in this case because using File.open with a block automatically handles opening and closing the file safely.

Modifying Routes for File Uploads

To handle file uploads, you need to update the routes.rb file to include routes for handling both GET and POST requests for the upload functionality. Add the following lines to your routes.rb:

resources :todos do
  member do
    get 'upload', to: 'todos#upload'
    post 'upload', to: 'todos#upload'
  end
end

In this snippet, the member block specifies that the routes are associated with a specific ToDo item. The get 'upload' route is used to display the upload form, while the post 'upload' route processes the file upload when the form is submitted. By adding these routes, you associate the upload functionality directly with individual ToDo items in your application.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal