1

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.

iGian
  • 11,023
  • 3
  • 21
  • 36
Bobby M
  • 11
  • 3

0 Answers0