Jaeger
Jaeger

Reputation: 1754

Issue with a nested form_for's parameter

I'm creating a website on which people can read mangas, thanks to three scaffolds : one for the manga itself, one for its chapters and a last one for the chapter's pages. In my routes.rb file, I nested the pages inside the chapter resources, which I nested inside the manga's, so my routes look like the following:

  resources :mangas do
    resources :chapters do
      resources :pejis #Rails doesn't like the "scan" word
    end
  end

I can create a manga without troubles, but for an unknown reason, I can't manage to make the form appear:

views/chapters/_form.html.erb

<%= form_for(chapter) do |f| %>

  <div class="field">
    <%= f.label :titre %>
    <%= f.text_field :titre %>
  </div>

  <div class="field">
    <%= f.label :apercu %>
    <%= f.file_field :apercu %>
  </div>

  <div class="field">
    <!-- Allows me to upload the chapter's pages in the same time -->
    <label for="images[]">Multi Upload</label>
    <%= file_field_tag 'images[]', type: :file, multiple: true %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

The form_for parameter is as it was when created by the scaffold command. However, obviously, it doesn't work since I nested the resources inside the manga scaffold. I tried a few things, until new_manga_chapter_path allowed me to see the form. However, when submitting it, I'm getting the following error: No route matches [POST] "/mangas/1/chapters/new". I'm not even sure if this is normal or strange.

I'm pretty sure I shouldn't put "new_manga_chapter_path" as parameter for the form_for but I have no idea what to put instead.

Just in case, here is the chapter controller:

class ChaptersController < ApplicationController
  before_action :set_chapter, only: [:show, :edit, :update, :destroy]

  def index
    @chapters = Chapter.all
  end

  def show
  end

  def new
    @chapter = Chapter.new

  end

  def edit
  end

  def create
    @chapter = Chapter.new(chapter_params)

    if @chapter.save
      (params[:images] || []).each_with_index do |image, index|
        @chapter.pejis.create(image: image, scan_number: index + 1)
      end
      redirect_to @chapter, notice: 'Chapter was successfully created.'
    else
      render :new
    end
  end

  def update
    if @chapter.update(chapter_params)
      (params[:images] || []).each_with_index do |image, index|
        @chapter.pejis.create(image: image, scan_number: index + 1)
      end
      redirect_to @chapter, notice: 'Chapter was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @chapter.destroy
    redirect_to chapters_url, notice: 'Chapter was successfully destroyed.'
  end

  private

    def set_chapter
      @chapter = Chapter.friendly.find(params[:id])
    end

    def chapter_params
      params.require(:chapter).permit(:titre, :apercu)
    end
end

Don't hesitate if you want to see something else

Thank you in advance

Upvotes: 0

Views: 39

Answers (1)

Graham Slick
Graham Slick

Reputation: 6870

Try this:

# don't replace the [] by ()
<%= form_for [@manga, @chapter] do |f| %>

Or

<%= form_for manga_chapter_path(@manga, @chapter) %>

And in your controller:

def new
  @manga = Manga.find(params[:manga_id])
  @chapter = Chapter.new
end

To help you after your comments: In your create method:

def create
    @manga = Manga.find(params[:manga_id])
    @chapter = Chapter.new(chapter_params)

    if @chapter.save
      (params[:images] || []).each_with_index do |image, index|
        @chapter.pejis.create(image: image, scan_number: index + 1)
      end
      redirect_to manga_chapter_path(@manga, @chapter), notice: 'Chapter was successfully created.'
    else
      render :new
    end
  end

Upvotes: 2

Related Questions