dev404
dev404

Reputation: 1098

Using form_for with nested resources. "Undefined method _index_path"

I'm trying to upload files on a form, using Carrierwave. So far, I've managed to 'nest' one model onto another, but now I'm having trouble to do the 'form_for' correctly.

The idea is to setup a page (index) that would list the photographs (Fotografias) corresponding to each individual (Individuo), and have the ability to add new ones in the same page.

I have the following models:

fotografia.rb

class Fotografia < ActiveRecord::Base
  belongs_to :individuo

  mount_uploader :title, ArchivoUploader
end

individuo.rb

class Individuo < ActiveRecord::Base
  has_many :fotografias
end

Controllers:

fotografias_controller.rb

class FotografiasController < ApplicationController
  before_action :set_individuo, only: [:index, :show, :edit, :create, :update, :destroy]
  before_action :set_fotografia, only: [:show, :edit, :update, :destroy]

  def index
     @fotografias = @individuo.fotografias
     @new_foto = @individuo.fotografias.build
  end

  def set_individuo
    @individuo = Individuo.find(params[:individuo_id])
  end

  def set_fotografia
    @fotografias = Fotografia.find(params[:id])
  end

  def fotografia_params
    params.require(:individuo).permit(:individuo_id, :title)
  end
end

title is the field that holds the file information in the model.

index.html.haml:

=form_for [@individuo,@new_foto] do |f|
  .row
    =f.file_field :title, :class => 'hidden'
    =f.label :title, 'New Fotografia', :class => 'btn btn-sm btn-primary'

I read that this might be a pluralization issue, but I don't think that's the case. These are my routes:

routes.rb

  resources :individuos do
    resources :fotografias
  end

rake routes output:

    individuo_fotografias GET    /individuos/:individuo_id/fotografias(.:format)          fotografias#index
                          POST   /individuos/:individuo_id/fotografias(.:format)          fotografias#create
 new_individuo_fotografia GET    /individuos/:individuo_id/fotografias/new(.:format)      fotografias#new
edit_individuo_fotografia GET    /individuos/:individuo_id/fotografias/:id/edit(.:format) fotografias#edit
     individuo_fotografia GET    /individuos/:individuo_id/fotografias/:id(.:format)      fotografias#show
                          PATCH  /individuos/:individuo_id/fotografias/:id(.:format)      fotografias#update
                          PUT    /individuos/:individuo_id/fotografias/:id(.:format)      fotografias#update
                          DELETE /individuos/:individuo_id/fotografias/:id(.:format)      fotografias#destroy

I apologize for the Spanish nomenclature, and other language mixups.

When I try to load http://localhost:3000/individuos/3/fotografias I get the following error: "undefined method individuo_fotografia_index_path for #<#:0x007fa05c5d44a0>", with the line responsible for the error being =form_for [@individuo,@new_foto] do |f|.

Any clues of what I'm missing?

Solution

Per answer by TK-421, I made this change to the form_for:

=form_for [@new_foto.individuo, @new_foto], :html => { :multipart => true }, :url => {:controller => 'fotografias', :action => 'create'} do |f|

This would ensure that it's going to the CREATE action in the Fotografias controller. Just to be thorough, here's the create action in the controller:

fotografias_controller.rb

def create
  @fotografia = @individuo.fotografias.new(fotografia_params)

  respond_to do |format|
    if @fotografia.save
      format.html { redirect_to individuo_fotografias_path, notice: 'Fotografias Actualizadas' }
    else
      format.html { render :new }
    end
  end
end

Upvotes: 1

Views: 709

Answers (1)

TK-421
TK-421

Reputation: 10763

Given the route output and error above, it appears that Rails is looking for individuo_fotografias_path (instead of individuo_fotografia_index_path).

But I'm not sure if that's your intent, based on the form_for example you provided.

You might try adding the url parameter to your form helper to be more specific: url: individuo_fotografias_path.

Or otherwise try some of the longer-form options of the helper as defined in the doc until you get it working the way you'd like.

Upvotes: 1

Related Questions