Table of Content
Associate photo to album
Before we associate the album and photo model, it would be better to plan the entry point — routes. By doing that, we can have a clear blueprint on how the app should redirect.
Target URL:
/ home page
/albums/new create album
/albums/:album_id show spceific album with photos
/albums/:album_id/photos/new create photo
/albums/:album_id/photos/:photo_id show specific photo
Important: Do not underestimate the power of URL design. It acts as the entry point of your web app. Your users bookmark it; They share it; They hack it; And Google indexes it.
Do not under estimate the power of URL design
We want to update the routes.rb
file to reflect our URL design.
The association starts in the model.
album.rb
file.
photo.rb
file.
Now photos is nested inside albums. This means all our photo actions will need the @album
instance. We can do that by using before_filter
(or before_action
in rails 4).
In the photos_controller.rb
file, add the before_filter line at the beginning and the private methods at the end, before the class end
.
Then we change all the Photo
reference to @album.photos
because every photos collection querying is bound by the @album.
And before saving the photo, we set the photo to the associated album again.
1@photo.album = @album
Note: before_filter means running the given method before running every actions. We can use :only action to run it only in a given list of methods. Or we can use :except for a list of methods that doesn’t run the given method.
Example on using before_filter:
And here is the full photos_controller.rb
file dump, in case you failed to complete the changes:
1class PhotosController < ApplicationController 2 3 before_filter :set_album 4 5 def show 6 @photo = @album.photos.find params[:id] 7 end 8 9 def new 10 @photo = @album.photos.new 11 end 12 13 def create 14 @photo = @album.photos.new params[:photo] 15 @photo.album = @album 16 if @photo.save 17 redirect_to @album 18 else 19 render :new 20 end 21 end 22 23 def edit 24 @photo = @album.photos.find params[:id] 25 end 26 27 def update 28 @photo = @album.photos.find params[:id] 29 30 if @photo.update_attributes params[:photo] 31 redirect_to @album 32 else 33 render :edit 34 end 35 end 36 37 private 38 def set_album 39 @album = Album.find params[:album_id] 40 end 41 42end
And then the views update.
views/photos/show.html.erb
file.
As a bonus, we can also create a breadcrumb when showing the photo:
views/photos/show.html.erb
file.
Note: As documented in the paperclip gem, we can use <attachment>_file_name
to refer to the filename string.
This is how the breadcrumb looks like:
views/photos/_form.html.erb
file.
First, we get the @album reference in the albums_controller.rb
file.
Now we can list all the photos in the album.
Add the views/albums/show.html.erb
file with the following HTML/ERB code
When test the code in browser, the albums list the photos and show the photo after clicking on it.
What’s next? We’re going to take a look at “Introducing asset pipeline”.