I have 3 models: Book
, UserBook
, and User
(from devise). User
and Book
are linked though UserBook
with a has_many:users through: :user_books
.
I've been trying to access the edit and destroy methods in user_books
using a simple form in books#show
to change a boolean value have_or_want
from false
to true
. These are the models:
class Book < ApplicationRecord
has_many :user_books
has_many :users, through: :user_books
validates :title, :author, presence: true
validates :rating, inclusion: {in: [1,2,3,4,5], allow_nill: false }
end
class UserBook < ApplicationRecord
belongs_to :user
belongs_to :book
end
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :user_books
has_many :books, through: :user_books
end
The idea is that you can look a book in books#show
and an if statement decides which of three simple_forms
is shown:
If there is no UserBook
linking the current_user
to the book there will be a radio button which if you want to add it to your own book collection (@user_book.have_or_want: true
) or add it to your reading list (@user_book.have_or_want: false
). This bit work and a new UserBook
is created correctly using user_books#update
.
I am now trying to have a form for when the book is on the users reading list(@user_book.have_or_want)
to give the option marking the book as read (change @user_book.have_or_want
to true
with user_books#update
) or to remove the book (user_books#destroy
).
Also a third form for if it is in the book collection (@user_book.have_or_want: true
) to remove it by deleting the @user_book
.
In the routes UserBook
is nested in Book
.
The if statement and simple forms in books#show
looks like this and the first part works.
<% if current_user.books.exclude? @book %>
<%= simple_form_for [@book, @user_book] do |f| %>
<%= f.input :have_or_want,
:collection => [[true, 'Add to Bookshelf'], [false, 'Add to resding
list']],
:label_method => :last,
:value_method => :first,
:as => :radio_buttons %>
<%= f.submit "Submit" %>
<% end %>
<% elsif @book.user_books[0].have_or_want == false %>
<!-- If is is on the reading list you can add to bookshelf(changes
have_or_want to true) or can remove from reading list (delete
user_book instance) -->
<%= simple_form_for [@book, @user_book], url:
book_user_book_path(@book, @user_book), method: :patch do |f| %>
<%= f.input :have_or_want %>
<%= f.submit "Submit" %>
<% end %>
<% else %>
<!-- It is on the bookshelf so option to remove - user_books#destroy?
-->
<% end %>
I have tried several ways to do the second part and this is my best guess at the moment. There error I get is:
No route matches {:action=>"show", :book_id=>"1", :controller=>"user_books", :id=>nil}, missing required keys: [:id]
Also @user_book
is a user_book
with all values of nil.