Search code examples
ruby-on-railsarraysassociationshas-and-belongs-to-manyjoin

A class was passed to `:class_name` but we are expecting a string


I'm trying to create a join table called :books_users where a column in books, :claim, is a boolean, where if a person clicks the link to "review this book", the claim action in the books controller does this:

def claim
    book = Book.find(params[:id])
    book.claims << current_user unless book.claims.include?(current_user)
    redirect_to current_user
    flash[:notice] = "You have a new book to review!"
  end

The purpose of this is for my users who are signed up as reviewers can go onto book show pages, and if they decide to review a book uploaded by an author which the reviewer finds through the genres? Then they essentially indicate they're gonna review that book, which their reveiew will eventually show up on amazon as a verified purchased review, not a cheesy text review on the site on the books show page (this will make the author who signs up for the review service very happy).

My models look like this:

book.rb 

class Book < ApplicationRecord
  mount_uploader :avatar, AvatarUploader
  belongs_to :user
  has_and_belongs_to_many :genres
  has_and_belongs_to_many :claims, join_table: :books_users, association_foreign_key: :user_id

end

user.rb

class User < ApplicationRecord
mount_uploader :avatar, AvatarUploader

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :books
  enum access_level: [:author, :reviewer]

  has_and_belongs_to_many :claims, join_table: :books_users, association_foreign_key: :book_id
end

When the reviewer clicks on the link to review the book I get a NameError in BooksController#claim

uninitialized constant Book::Claim

I have tried to specify in the hmbtm relationships in the model after the foreign_key_association is named, I do a class_name: ClassName, thinking that might take care of the error, but I get a new one saying A class was passed to :class_name but we are expecting a string.

I'm really confused and need someone to explain this to me. Thanks!


Solution

  • The error says you should pass string as class_name argument or you can use undocumented class option:

    class Foo < AR
      has_many :bars, class_name: to_s 
      # to_s returns the class name as string the same as Bar.class.to_s
    end
    

    or:

    class Foo < AR
      has_many :bars, class: Baz # returns the class
    end