Hi I currently have 3 models: user, album, photo. I've made registration, but not login/sessions yet, since I am trying to have the album/photo creation finished first. However, when I create an album the URL changes from
http://localhost:3000/users/13/albums/new
(no problem)
to
http://localhost:3000/albums/76/photos/76
(problem)
the issues here are:
1. the user_id disappears from the url.
2. it's sending me to the wrong url. As you can see below, I am redirecting to [@user, @album]. Isn't that supposed to be the show action of the albums controller? I wanted something like /users/13/albums/1 as the url. Instead, it's sending me to photos#show
.
3. even though it's the wrong link, why are the album id and the photo id are always the same? 76/76 77/77 etc... I don't know where that is coming from..
here are my files:
album controller
def show
@user = User.find(params[:user_id])
@album = @user.albums.find(params[:id])
@photo = @album.photos.build(params[:photo])
respond_to do |format|
if @album.save
format.html { redirect_to album_photo_path(@album), notice: 'Album was successfully created.' }
format.json { render json: @album, status: :created, location: @album}
else
format.html { render action: "new" }
format.json { render json: @album.errors, status: :unprocessable_entity }
end
end
end
def update
end
def edit
end
def create
@user = User.find(params[:user_id])
@album = @user.albums.build(params[:album])
respond_to do |format|
if @user.save
format.html { redirect_to [@user, @album], notice: 'Album was successfully created.' }
format.json { render json: @album, status: :created, location: @album}
else
format.html { render action: "new" }
format.json { render json: @album.errors, status: :unprocessable_entity }
end
end
end
albums/new.html.erb
<%= form_for (@album), url: user_albums_path, :html => { :id => "uploadform", :multipart => true } do |f| %>
<div>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :description %>
<%= f.text_area :description %>
<br>
<%=f.submit %>
</div>
<% end %>
config/routes
Pholder::Application.routes.draw do
resources :users do
resources :albums
end
resources :albums do
resources :photos
end
let me know if you need anymore files.
Here's the series of requests that your use case runs through:
First, the form submits some data to your Album#create
action.
After the Album#create
request succeeds, the request is redirected to the Albums#show
action.
In the Albums#show
action, the controller instantiates @user
and @album
with your current User and the new Album, then builds a new Photo object within the Album's photos
collection.
The action then saves the Album
record again. Since nothing has changed, this doesn't actually do anything. But it does do nothing successfully, so it proceeds to redirect the request to album_photo_path
, and this is where things go pear-shaped. This route, as defined, leads to a Photo#show
action, in the context of the photo's parent Album. The route expects two arguments, an Album and a Photo. As invoked in your code, it shouldn't work—throwing a Routing Error exception instead. (Believe me, I tried.)
Instead of getting hung up on minutae like that, though, I'm going to make a blind recommendation instead!
It sounds like you didn't intend for your Album#show
action to save the album and redirect to Photo#show
via a malformed route. I think this is the source of all three of your issues. And, ultimately, I think your AlbumsController
's show
action needs to look like this:
def show
@user = User.find(params[:user_id])
@album = @user.albums.find(params[:id])
end
Hope this helps!
Absolutely, you can set up the Album#show
action to allow users to add photos. This would involve two changes to what I suggest above.
In your controller, you would instantiate a new Photo on @album
's Photos collection, much as you had earlier:
def show
@user = User.find(params[:user_id])
@album = @user.albums.find(params[:id])
@photo = @album.photos.build
end
Then, in the Album#show
template (e.g. app/views/albums/show.html.erb
), you'd include a form for submitting a new photo:
<%= form_for [@user, @album, @photo] do |f| %>
<%= f.text_field :caption %>
<%= f.file_field :image %>
<%- end %>
This form would submit its contents to the user_album_photos_path
, which you may note does not yet exist. So the final change would be to nest Photos as a resource in routes.rb
:
resources :users do
resources :albums do
resources :photos
end
end
This will provide you with the route needed to use the form. Now you'll just need to add a Photo#create
action to handle the form submission, and you're off to the races!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With