Ruby on Rails API中Book.all返回空结果问题排查
Rails API中Book.all返回空数组的问题排查与解决
我是Ruby on Rails开发新手,正在构建包含User、Book、Author、Shelf类的API。调用Book.all获取数据库中所有书籍时返回[],不清楚问题所在。以下是相关代码:
迁移文件
class CreateBooks < ActiveRecord::Migration[7.0] def change create_table :books do |t| t.string :title t.references :user, null: false, foreign_key: true t.timestamps end end end
Book模型
class Book < ApplicationRecord belongs_to :user belongs_to :author belongs_to :shelf end
Books控制器
class Api::BooksController < ApplicationController def index books = Book.all render json: book end def show book = Book.find(params[:id]) render json: book end def create book = Book.new(book_params) if book.save render json: book, status: :created else render json: { errors: book.errors.full_messages }, status: :unprocessable_entity end end def destroy book = Book.find(params[:id]) if book.destroy render json: { message: 'Book was deleted successfully' } else render json: { error: 'Failed to delete the Book' }, status: :unprocessable_entity end end private def book_params params.require(:book).permit(:title) end end
我期望能看到已创建的书籍名称,以下是我在Rails控制台创建书籍的方式:
book = Book.new(title: "Pearl of Great Price")
问题原因及解决方法
控制台创建书籍未保存
Book.new仅初始化了Book对象,并未写入数据库。需调用book.save完成保存,或直接使用Book.create(title: "Pearl of Great Price")一步完成创建与保存。模型关联缺失必要字段
Book模型声明了belongs_to :author和belongs_to :shelf,但迁移文件仅添加了user_id外键,无author_id和shelf_id。默认情况下Rails的belongs_to关联为必填项,会导致书籍保存失败。- 解决方式二选一:
- 添加迁移文件补充字段:生成新迁移添加
t.references :author, foreign_key: true和t.references :shelf, foreign_key: true,运行rails db:migrate生效。 - 修改模型将非必填关联设为可选:
class Book < ApplicationRecord belongs_to :user belongs_to :author, optional: true belongs_to :shelf, optional: true end
- 添加迁移文件补充字段:生成新迁移添加
- 解决方式二选一:
控制器index方法拼写错误
index方法中定义了books = Book.all,但渲染时写的是render json: book——book为未定义变量,需改为render json: books,否则调用接口会抛出异常。创建书籍时未传入必填的user_id
迁移文件中user关联设置了null: false,创建书籍必须传入有效user_id。控制台创建需先存在User对象:# 假设User模型有name字段 user = User.create(name: "测试用户") book = Book.create(title: "Pearl of Great Price", user_id: user.id)或通过关联直接创建:
user.books.create(title: "Pearl of Great Price")
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

