ActiveRecord::Fixture::FixtureError: table “books” has no column named “loves”

和自甴很熟 提交于 2019-12-07 16:55:40

问题


Bizarre Rails problem.

I have a Book entity and users can Love a book.

All my other models are fine and passing all the tests but after generating the new Love model and setting the fixtures, I am getting a ton of these errors out of the blue:

ActiveRecord::Fixture::FixtureError: table "books" has no column named "loves".

I somehow think it's to do with reserved keywords in Rails perhaps?

Is Love a reserved keyword by any chance?

I did a search on this page:

https://reservedwords.herokuapp.com/

And the word love yields no results.

Love Migration File

class CreateLoves < ActiveRecord::Migration[5.0]
  def change
    create_table :loves do |t|
      t.references :book, foreign_key: true
      t.references :sender, foreign_key: true
      t.references :receiver, foreign_key: true

      t.timestamps
    end
  end
end

Love Model

class Love < ApplicationRecord
  belongs_to :book
  belongs_to :sender, class_name: "User"
  belongs_to :receiver, class_name: "User"
end

Love Fixtures

one:
  book: one
  sender: jim
  receiver: sarah

two:
  book: two
  sender: sarah
  receiver: jim

three:
  book: three
  sender: jim
  receiver: tycus

Book Model

class Book < ApplicationRecord
  belongs_to :author, class_name: "User"
  has_and_belongs_to_many :genres
  has_many :loves
end

Book Fixtures

one:
  title: Back To The Future
  adult_content: true
  author: jim
  published: false
  genres: action, comedy, science_fiction

two:
  title: Harry Potter and The Philosopher's Stone
  adult_content: false
  author: sarah
  published: false
  genres: action, fantasy

three:
  title: Back To The Future 2
  adult_content: true
  author: jim
  published: false
  genres: action, comedy, science_fiction

four:
  title: Back To The Future 3
  adult_content: true
  author: jim
  published: false
  genres: action, comedy, science_fiction

five:
  title: Royal Guard
  adult_content: true
  author: chewedon
  published: false
  genres: action, romance, fantasy

Books Controller

class BooksController < ApplicationController
  before_action :authenticate_user
  after_action :verify_authorized, except: [:index, :create]
  after_action :verify_policy_scoped, only: :index

  def index
    books = policy_scope(Book.all)
    render json: books
  end

  def create
    book = Book.new(book_params)

    if book.save
      render json: book, status: :created
    else
      render status: :unprocessable_entity
    end
  end

  def show
    book = Book.find_by(id: params[:id])

    if book.present?
      authorize book
      render json: book
    else
      skip_authorization
      render status: :not_found
    end
  end

  def update
    book = Book.find_by(id: params[:id])

    skip_authorization and render status: :not_found and return unless book

    authorize book

    if book.update!(book_params)
      render json: book
    else
      render status: :unprocessable_entity
    end
  end

  def destroy
    book = Book.find_by(id: params[:id])

    skip_authorization and render status: :not_found and return unless book

    authorize book

    if book.destroy!
      render status: :ok
    end
  end


  private

  def book_params
    params.permit(:title, :adult_content, :published, :author_id, genre_ids: [])
  end
end

Here are some of my other model and their test fixtures, they all pass the tests:

Chapter Fixtures

one:
  title: Straw House
  order: 1
  content: First pig built a house out of straw
  published: true
  book: one

two:
  title: Wooden House
  order: 2
  content: Second pig built a house out of wood
  published: true
  book: one

three:
  title: Brick House
  order: 3
  content: Third pig built a house out of brick
  published: false
  book: one

four:
  title: Hogwarts School of Wizardry
  order: 1
  content: They pushed their troller into nine and three quarters
  published: false
  book: two

Comment Fixtures

one:
  content: Love this chapter
  author: jim
  book: one
  chapter: one

two:
  content: Hate this chapter
  author: sarah
  book: two
  chapter: two

three:
  content: Interesting chapter
  author: tycus
  book: one
  chapter: one

Message Fixtures

one:
  subject: Next Chapter
  body: When will the next chapter be published?
  sender_read: false
  receiver_read: false
  sender: jim
  receiver: sarah

two:
  subject: Film Adaptation
  body: I would like to turn your story into a film
  sender_read: false
  receiver_read: false
  sender: sarah
  receiver: jim

three:
  subject: Mind Blown
  body: Where do you get all these ideas? I'll stalk you now!
  sender_read: false
  receiver_read: false
  sender: tycus
  receiver: jim

What could be the problem?

Update

If I comment out my Love Fixtures:

# one:
#   book: one
#   sender: jim
#   receiver: sarah
#
# two:
#   book: two
#   sender: sarah
#   receiver: jim
#
# three:
#   book: three
#   sender: jim
#   receiver: tycus

I get new test errors:

Error:
BooksControllerTest#test_book_show_-_should_show_book_info:
NameError: uninitialized constant Book::Lofe
    app/controllers/books_controller.rb:26:in `show'
    test/controllers/books_controller_test.rb:63:in `block in <class:BooksControllerTest>'

Where the heck did Lofe come from?

I quadruple checked my spelling of Love. I even did an entire project search for word "Lofe" and it doesn't show any search results matching.


回答1:


Wild guess, but I think, it's because of how Inflector treats your has_many :loves line.

I think it assumes, that singular from loves is lofe, thus the error, because it tries to resolve the constant Lofe in the scope of Book class.

To override the default behaviour, see the very first block of code from the docs:

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.irregular 'octopus', 'octopi'
  # for your case it's
  inflect.irregular 'love', 'loves'
end



回答2:


@andreyDeineko is right, if you do "loves".singularize you get lofe

You can override how rails determines singular / plural in your environment or application rb

ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'love', 'loves'
end


来源:https://stackoverflow.com/questions/40846420/activerecordfixturefixtureerror-table-books-has-no-column-named-loves

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!