1

I am following the first part of Ryan Bate's episode #285. Not sure why it is not working. Here is the code:

models:

class Comic < ActiveRecord::Base
    has_many :comics_genres
    has_many :genres, through: :comics_genres
end

class ComicsGenre < ActiveRecord::Base
    belongs_to :genre
    belongs_to :comic
end

class Genre < ActiveRecord::Base
    has_many :comic_genres
    has_many :comics, through: :comics_genre
end

form for creating new comics:

  <%= form_for ([@user, @comic]) do |f| %>
    <div><%= f.collection_select :genre_ids, Genre.order(:genre), :id, :genre, {}, {multiple: true} %></div>

      <%= f.submit class: "btn btn-primary" %>
  <% end %>

Comic controller:

def create
    @user = current_user
    @comic = @user.comics.new(comic_params)

    respond_to do |format|
      if @comic.save
        format.html { redirect_to @comic, notice: 'Comic was successfully created.' }
        format.json { render action: 'show', status: :created, location: @comic }
      else
        format.html { render action: 'new' }
        format.json { render json: @comic.errors, status: :unprocessable_entity }
      end
    end
  end

def comic_params
      params.require(:comic).permit(:id, :title, :synopsis,
        comic_pages_attributes: [:comic_page_image],
        comics_genres_attributes: [:genre_id, :comic_id])
    end

In the console, I get records like this:

The issue is that genre_id is nil, but I am not sure how to get it to pass the right values.

Many thanks!

Jayway
  • 95
  • 2
  • 8
  • 1
    just use the form builder to build the collection select: `f.collection_select :genre_ids (etc)` Using this form builder will scope the collection_select in `params[:user][:comic][:genre_ids]` – MrYoshiji Jan 29 '14 at 18:14
  • My apologies. I meant to type f.collection_select ... I guess I am having a hard time writing the params to the comics_genre table. – Jayway Jan 29 '14 at 18:38

1 Answers1

1

I figured it out. Thanks to MrYoshi for the params. The form provides an array of genre ids which I set to the variable @genre_ids. After the comic is saved, I iterate through that array and save each genre id with the comic id to create records for the comics_genres table, which is the connector for comics and genres.

The confusing part was that saving the ComicsGenre instances can't happen until the comic is saved, because it only generates a comic id after the save.

Please let me know if this is not the best way of doing this! I am sure there is a more elegant way.

def create
    @user = current_user
    @comic = @user.comics.new(comic_params)
    @genre_ids = params[:comic][:genre_ids]

    respond_to do |format|
      if @comic.save

        @genre_ids.each do |genre_id|
          ComicsGenre.create(:comic_id => @comic.id, :genre_id => genre_id)
        end

        format.html { redirect_to @comic, notice: 'Comic was successfully created.' }
        format.json { render action: 'show', status: :created, location: @comic }
      else
        format.html { render action: 'new' }
        format.json { render json: @comic.errors, status: :unprocessable_entity }
      end
    end
  end
Jayway
  • 95
  • 2
  • 8