Add picture uploads
The ideas we added in the previous guide can benefit from a visual element, like a picture or drawing to spark the imagination. We can attach pictures by adding a file upload to the Idea model.
Setting up Active Storage
Rails comes with a built-in feature to handle file uploads, called Active Storage. Before we can use it, we need to set it up in the app.
Open the Terminal app and press Ctrl+C to quit the Rails server.
Then run the following commands in the Terminal:
rails active_storage:install
rails db:migrateThe first command prepares a change to the database, called a migration. The second command updates the database with the tables Active Storage uses to keep track of uploaded files.
Explain what Active Storage is and how it stores the uploaded files. What are database migrations and why do we need to run them?
Resource: Rails Guides Active Storage Overview
Attaching the picture to the idea model
Rails now knows a way to store file uploads in your app. It needs a bit of help to understand where you want to attach these uploads to.
Open the app/models/idea.rb file in your Text Editor. This file is used to store your ideas in the database and fetch the ideas to show them. We’ll change it to tell Rails every idea can have a picture.
Under the following line:
class Idea < ApplicationRecordadd this line and save the file:
has_one_attached :pictureThis has_one_attached line tells the Idea model that every idea can have one file attached to it, named picture. Active Storage will store the file upload and link it to the idea to display it later.
Adding the picture to the form
Now that your Idea model can have a picture attached, we can change the form to create and edit ideas to select a picture.
Open the app/views/ideas/_form.html.erb file in your Text Editor and find these lines near the bottom of the file:
<div>
<%= form.submit %>
</div>Above these lines, add the following lines and save the file:
<div>
<%= form.label :picture, style: "display: block" %>
<%= form.file_field :picture %>
</div>The file_field helper adds a new element to the form: a file chooser, recognizable by either a “Browse…” or “Choose File” button.
Allowing the picture to be saved
There’s one more change we need to make. For safety reasons, Rails only saves the form fields the app explicitly lists as allowed. Our new picture field is not on that list yet, so it would be ignored when the form is submitted.
Open the app/controllers/ideas_controller.rb file in your Text Editor and find the following line near the bottom of the file:
params.expect(idea: [ :name, :description ])Change it to this line and save the file:
params.expect(idea: [ :name, :description, :picture ])If your file shows params.require(:idea).permit(:name, :description) instead, add :picture to the end of that list in the same way.
Explain what strong parameters are and why Rails wants apps to list which form fields can be saved.
Uploading pictures
Run rails server.
In your browser open http://localhost:3000/ideas/new. Your “New idea” form will now show the new “Picture” field with the file chooser.
Fill in the form to create a new idea, and select a picture using this new element/button. Any random image you have on your laptop will do, it’s just a test.
Displaying the picture
You’ve now added a picture to your idea! You can’t see it yet after creating the idea, the pages don’t show it. Let’s change it so it shows the picture.
Open the app/views/ideas/_idea.html.erb file in the Text Editor and find the last line:
</div>Above this line, add the following line and save the file:
<%= image_tag(idea.picture, width: 600) if idea.picture.attached? %>Using the image_tag we have told Rails to display the file upload as an image if it is present on the idea. Ideas without a picture will not show one.
Refresh the Browser. Your uploaded image should now be visible!
Where are the pictures stored?
While developing your app, Active Storage saves the uploaded files in the storage folder of your app. Rails already configured Git to ignore this folder, so the uploaded pictures won’t be saved with your app source code.
Show the storage folder and the entry ignoring it in the .gitignore file. Explain why uploads shouldn’t be stored in the app source code, and how apps that are online usually store uploads in a cloud storage service instead.
If you’re ever stuck during a guide, please ask your coach for help and also consult this handy cheatsheet for Ruby, Rails, the console, the Text Editor etc.
Guides
- Guide 1: Start of the guide
- Guide 2: Get to know the tools
- Guide 3: Guide to install Rails
- Guide 4: Build Your First App
- Guide 5: Style your app using HTML and CSS
- Guide 6: Add a new page to your app
- Guide 7: Add a new homepage to your app
- Guide 8: Add picture uploads (Current page!)
- Guide 9: Push Your App to GitHub
- Guide 10: Put your app online with one of these services:
- Guide 11: Style the idea pages using HTML and CSS
- Guide 12: Add comments to your app
- Guide 13: Create picture thumbnails
- Guide 14: Test your app with RSpec