Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's the series of requests that your use case runs through:</p> <p>First, the form submits some data to your <code>Album#create</code> action.</p> <p>After the <code>Album#create</code> request succeeds, the request is redirected to the <code>Albums#show</code> action.</p> <p>In the <code>Albums#show</code> action, the controller instantiates <code>@user</code> and <code>@album</code> with your current User and the new Album, then builds a new Photo object within the Album's <code>photos</code> collection.</p> <p>The action <em>then</em> saves the <code>Album</code> record again. Since nothing has changed, this doesn't actually do anything. But it does do nothing <em>successfully</em>, so it proceeds to redirect the request to <code>album_photo_path</code>, and <strong>this is where things go pear-shaped</strong>. This route, as defined, leads to a <code>Photo#show</code> action, in the context of the photo's parent Album. The route expects <em>two</em> arguments, an Album and a Photo. As invoked in your code, it <em>shouldn't work</em>—throwing a Routing Error exception instead. (Believe me, I tried.)</p> <p>Instead of getting hung up on minutae like that, though, I'm going to make a blind recommendation instead!</p> <p>It sounds like you didn't intend for your <code>Album#show</code> action to save the album and redirect to <code>Photo#show</code> via a malformed route. I think this is the source of all three of your issues. And, ultimately, I think your <code>AlbumsController</code>'s <code>show</code> action needs to look like this:</p> <pre><code>def show @user = User.find(params[:user_id]) @album = @user.albums.find(params[:id]) end </code></pre> <p>Hope this helps!</p> <hr> <h3>Edited to address Edmund's comment:</h3> <p>Absolutely, you can set up the <code>Album#show</code> action to allow users to add photos. This would involve two changes to what I suggest above.</p> <p>In your controller, you would instantiate a new Photo on <code>@album</code>'s Photos collection, much as you had earlier:</p> <pre><code>def show @user = User.find(params[:user_id]) @album = @user.albums.find(params[:id]) @photo = @album.photos.build end </code></pre> <p>Then, in the <code>Album#show</code> template (e.g. <code>app/views/albums/show.html.erb</code>), you'd include a form for submitting a new photo:</p> <pre><code>&lt;%= form_for [@user, @album, @photo] do |f| %&gt; &lt;%= f.text_field :caption %&gt; &lt;%= f.file_field :image %&gt; &lt;%- end %&gt; </code></pre> <p>This form would submit its contents to the <code>user_album_photos_path</code>, which you may note does not yet exist. So the final change would be to nest Photos as a resource in <code>routes.rb</code>:</p> <pre><code>resources :users do resources :albums do resources :photos end end </code></pre> <p>This will provide you with the route needed to use the form. Now you'll just need to add a <code>Photo#create</code> action to handle the form submission, and you're off to the races!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload