Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3, nested resource, No route matches [PUT]

I'm literately going crazy with this one. I have been searching the answer and trying everything I find, including related questions & answers here on stackoverflow and still can't make it work.

I'm working with a nested resource and I can't make the form work. I always get errors, such as No route matches [PUT] "/galleries/1/photos"

The form is here: /galleries/1/photos/1/edit

routes.rb

resources :galleries do
  resources :photos
end
resources :galleries
resources :photos

photos_controller.rb

def new
  @gallery = Gallery.find(params[:gallery_id])
  @photo = @gallery.photos.build

  respond_to do |format|
    format.html
  end
 end

def edit
  @gallery = Gallery.find(params[:gallery_id])
  @photo = Photo.find(params[:id])
end

def create
  @gallery = Gallery.find(params[:gallery_id])
  @photo = @gallery.photos.build(params[:photo])

  respond_to do |format|
    if @photo.save
      format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end

def update
  @gallery = Gallery.find(params[:gallery_id])
  @photo = Photo.find(params[:id])

  respond_to do |format|
    if @photo.update_attributes(params[:photo])
      format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
      format.json { head :ok }
    else
      format.html { render action: "edit" }
      format.json { render json: @photo.errors, status: :unprocessable_entity }
    end
  end
end

_form.html.erb

<%= form_for([@gallery, @photo], :url => gallery_photos_path(params[:gallery_id]), :html => {:multipart => true}) do |f| %>
  <div class="field">
  <%= f.label :title %><br />
  <%= f.text_field :title %>
</div>
<div class="field">
  <%= f.file_field :image %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

I have also tried form_for([@gallery, @photo], :html => {:multipart => true}) and form_for(@photo, :url => gallery_photos_path(@gallery), :html => {:multipart => true})

UPDATE

Here is a portion of rake routes.

gallery_photos GET    /galleries/:gallery_id/photos(.:format)          {:action=>"index", :controller=>"photos"}
    POST   /galleries/:gallery_id/photos(.:format)          {:action=>"create", :controller=>"photos"}
new_gallery_photo GET    /galleries/:gallery_id/photos/new(.:format)      {:action=>"new", :controller=>"photos"}
edit_gallery_photo GET    /galleries/:gallery_id/photos/:id/edit(.:format) {:action=>"edit", :controller=>"photos"}
gallery_photo GET    /galleries/:gallery_id/photos/:id(.:format)      {:action=>"show", :controller=>"photos"}
    PUT    /galleries/:gallery_id/photos/:id(.:format)      {:action=>"update", :controller=>"photos"}
    DELETE /galleries/:gallery_id/photos/:id(.:format)      {:action=>"destroy", :controller=>"photos"}
like image 704
leonel Avatar asked Sep 14 '11 16:09

leonel


2 Answers

You don't need to specify the URL, which was wrong for the update anyway. Try

<%= form_for([@gallery, @photo], :html => {:multipart => true}) do |f| %>
like image 164
Wizard of Ogz Avatar answered Oct 24 '22 23:10

Wizard of Ogz


Answer off top of my head. I don't have working example, but hope it helps.

In deed, according to your rake routes, you don't have a route:

[PUT] "/galleries/1/photos"

If I'm not mistaken, your form points to invalid action: gallery_photos_path will return an index of photos in gallery with id :gallery_id. I think, :url parameter of the form should be something like:

:url => gallery_photo_path(params[:gallery_id], params[:id])

OR you can specify it without using Rails helpers:

:url => "/galleries/#{params[:gallery_id]}/photos/#{params[:id]}"

Also, if you are trying to create nested resource, I don't think you need these lines in your routes file:

resources :galleries
resources :photos
like image 27
Simon Bagreev Avatar answered Oct 24 '22 23:10

Simon Bagreev