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

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

奇怪的 Rails 问题。

我有一个 Book 实体,用户可以 Love 一本书。

我的所有其他模型都很好并通过了所有测试,但是在生成新的 Love 模型并设置固定装置后,我突然遇到了很多这样的错误:

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

我不知何故认为这可能与 Rails 中的保留关键字有关?

Love 是保留关键字吗?

我在这个页面上搜索过:

https://reservedwords.herokuapp.com/

单词love没有结果。

爱迁移文件

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

恋爱模特

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

爱情装置

one:
  book: one
  sender: jim
  receiver: sarah

two:
  book: two
  sender: sarah
  receiver: jim

three:
  book: three
  sender: jim
  receiver: tycus

图书模型

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

书架

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

书籍控制器

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

这是我的一些其他模型和他们的测试治具,他们都通过了测试:

章节赛程

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

评论赛程

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

消息装置

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

可能是什么问题?

更新

如果我注释掉我的 Love Fixtures:

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

我收到新的测试错误:

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>'

Lofe 到底是从哪里来的?

我四次检查了 Love 的拼写。我什至在整个项目中搜索单词 "Lofe",但没有显示任何匹配的搜索结果。

胡乱猜测,但我认为,这是因为 Inflector 对待您的 has_many :loves 台词的方式。

我认为它假定 loves 中的单数是 lofe,因此是错误,因为它试图解析 Book 范围内的常量 Lofe class.

要覆盖默认行为,请参阅文档中的第一段代码:

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

@andreyDeineko 是对的,如果你这样做 "loves".singularize 你会得到 lofe

您可以覆盖 rails 在您的环境或应用程序 rb

中确定单数/复数的方式
ActiveSupport::Inflector.inflections do |inflect|
  inflect.irregular 'love', 'loves'
end