I have two example classes:
# book.rb
class Book < ApplicationRecord
has_and_belongs_to_many :tag
end
# tag.rb
class Tag < ApplicationRecord
has_and_belongs_to_many :formula
end
If I understand correctly, this means that I could eventually have tags with many books and books with many tags. Right now, I want to assign tags to books when I create books.
I have a multiselect dropdown on the books/new page to send these tags to the controller, but I don't know what to do once they reach the controller.
<div>
<%= form.label :tags, style: "display: block" %>
<%= select_tag :tags, options_from_collection_for_select(@tags, :id, :name), multiple: true, prompt: "Select Tags" %>
</div>
Controller looks like this:
def create
@Book = Book.new(book_params)
respond_to do |format|
if @book.save
format.html { redirect_to book_url(@book), notice: "Book was successfully created." }
format.json { render :show, status: :created, location: @book }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @book.errors, status: :unprocessable_entity }
end
end
end
When I make a book with the form, it doesn't have any tags when I inspect the latest book in the rails console.
I tried putting @book.tag.build(tag_ids: book_params["tags"]) into thee create method but that didn't work and I feel like I'm barking up the wrong tree.
CodePudding user response:
You may add accepts_nested_attributes_for :tags
in the Book
model. This way, when the form is submitted, @book.save
will create the associations for tags from params[:books][:tags]
# book.rb
class Book < ApplicationRecord
has_and_belongs_to_many :tag
accepts_nested_attributes_for :tags
end
Reference: https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
CodePudding user response:
If you want to assign existed tags to new book, you can use select
method in your form
<%= form.select :tag_ids, Tag.all.map { |p| [p.name, p.id] }, multiple: true, prompt: "Select Tags" %>
Of course you can pass @tags
from controller instead of Tag.all
If you use strong params, you need to add this param there, something like
params.require(:book).permit(
# existed params,
tag_ids: []
)