Traveler7
Traveler7

Reputation: 195

How to create a form for a has_many through relationship?

In my app i have an index page of books from a Books Model. Think of it as a library.

Now i have Boards that consist of lists. Lets say i have a board called Categories.

So i go to the Categories Board. In my url it is www.example.com/board/1

On this categories board there are many lists. Lets say i have a list called programming books.

So now i need to add books to this list called Programming Books.

I have everything setup i just don't know how to add the books to the list. When i click the add books how do i get that list_id? I want to be able to click add books then it goes to a page that lists all the books. I then want to select the books by checking each one then add them to the list.

Don't worry about the creating the lists or boards i have that setup correctly i am just trying to add books to a list.

Categories Board (www.example.com/board/1)

===================     ===================     
=Programming Books=     =Adventure Books  =
===================     ===================
= Book 1          =     = add books       =
= Book 2          =     =                 =
= Book 3          =     =                 =
= add books       =     =                 =
===================     ===================

List Model

belongs_to :user, inverse_of: :list

has_many :list_books
has_many :books, through: :list_books

accepts_nested_attributes_for :list_books, :allow_destroy => true

List_Books Model

belongs_to :list
belongs_to :books

Book Model

belongs_to :user, inverse_of: :books

has_many :list_books
has_many :lists, through: :list_books

accepts_nested_attributes_for :list_books, :allow_destroy => true

List Controller

def addbooks
  // Not sure what to put here? It needs to grab the list_id from the list where i clicked add books.
end

private
  def_params
    // Not sure what params i need
  end

AddBooks View

// i need of list of all the books here. Then i want to check each book i want and then submit.

Upvotes: 1

Views: 113

Answers (1)

Moustafa Samir
Moustafa Samir

Reputation: 2268

You don't need to handle it in a seperate action, just the regular create action and add accept_nest_attributes as in this example

class Book < ActiveRecord::Base 
    has_many :classifications, :dependent => :destroy, :autosave => true , :inverse_of => :book accepts_nested_attributes_for :classifications, :allow_destroy => true, :reject_if => :all_blank 
    has_many :categories, :through => :classifications 
end


class Category < ActiveRecord::Base 
   has_many :classifications, :dependent => :destroy, :autosave => true , :inverse_of => :category accepts_nested_attributes_for :classifications, :allow_destroy => true, :reject_if => :all_blank 
  has_many :books, :through => :classifications 
end


class Classification < ActiveRecord::Base 
  belongs_to :category, :inverse_of => :classifications 
  belongs_to :book, :inverse_of => :classifications 
end

and then add it in your view.

<%= form_for @book do |f| %>

 <p>
 <%= f.label :name %>
 <%= f.text_field :name %>
 </p>

 <p>Categories</p>
 <ul>
 <% @categories.each do |cat| %>
 <%= hidden_field_tag "book_category_ids_none", nil, {:name => "book[category_ids][]"}%>
 <li>
 <%= check_box_tag "book_category_ids_#{cat.id}", cat.id, (f.object.categories.present? && f.object.categories.include?(cat.id)), {:name => "book[category_ids][]"} %>
 <%= label_tag "book_category_ids_#{cat.id}", cat.name %>
 </li>
 <% end %>
 </ul>

 <%= f.submit %>

<% end %>

check full example here

Upvotes: 1

Related Questions