Начнем с базы данных.Мы создадим отношение имеет-и-принадлежит-многим ,
create_table :books do |t|
t.string :name
t.timestamps
end
create_table :genres do |t|
t.string :name
t.timestamps
end
create_table :books_genres do |t|
t.references :book, foreign_key: true
t.references :genre, foreign_key: true
end
add_index :books_genres, [:book_id, :genre_id], unique: true
Теперь добавим ассоциацию для моделей:
# app/models/book.rb
class Book < ApplicationRecord
has_and_belongs_to_many :genres
end
# app/models/genres.rb
class Genre < ApplicationRecord
has_and_belongs_to_many :books
end
Что касаетсяПользовательский интерфейс, мы могли бы использовать стандартный HTML Multiple Select , но это действительно не удобно для пользователя, поэтому мы будем использовать флажки.
# config/routes.rb
resources :books # this is too much, but you will probably use other actions anyway.
# app/controllers/books_controller.rb
def new
@book = Book.new
@genres = Genre.all
end
# app/views/books/new.html.erb
<%= form_with(model: @book, local: true) do |form| %>
<%= form.label :name %>
<%= form.text_field :name %>
<% @genres.each_with_index do |genre, i| %>
<%= check_box_tag "book[genre_ids][#{i}]", genre.id %>
<%= label_tag "book[genre_ids][#{i}]", genre.name %>
<% end %>
<%= form.submit %>
<% end %>
Теперь мы должны сделать немного магии вконтроллер, так как мы получим genre_ids как хеш ({"0" => "1", "1" => "3"}
), это преобразует его в [1, 3]
# app/controllers/books_controller.rb
def book_params
params[:book][:genre_ids] = (params[:book][:genre_ids] || {}).values.map(&:to_i)
params.require(:book).permit(:name, genre_ids: [])
end
И, наконец, мы можем приступить к созданию книг
# app/controllers/book_controller.rb
def create
@book = Book.new(book_params)
if @book.save
redirect_to @book
else
render :new
end
end
Чтобы увидеть какие-либо флажки, вам нужно иметь свои жанры в базе данных.Вы можете легко сделать это с помощью rails console
:
%w[Adventure Tragedy Fantasy].each { |g| Genre.create(name: g) }
Флажки могут быть не лучшим пользовательским интерфейсом для этого, вы можете использовать Google для удобного множественного выбора, но это должно объяснить вам основычто вы пытаетесь достичь.