You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails Active Admin创建Book模型失败,其他模型正常

问题:Active Admin创建Book记录失败,返回200而非302重定向

尝试通过Active Admin仪表板创建新Book记录,点击创建按钮后无新记录生成。POST请求发送至/admin/books并携带表单数据,但服务器返回200状态码并重新渲染创建表单,而非302重定向到书籍列表。手动在控制器添加new和create方法可正常创建记录,仅Book模型受此影响,其他模型创建功能正常。使用默认Book表单时genre_id不显示,但仍存在相同创建失败问题。

环境:Ruby 3.4.1,Rails 8.0.2


admin/books.rb 代码

ActiveAdmin.register Book do
  permit_params :title, :page_count, :book_type, :year_released, :price, :genre_id, :language_id, :author_id

  # 下拉菜单及其他输入项显示正常,顺序符合预期
  form do |show|
    show.inputs "Details" do
      show.input :language_id, as: :select, collection: Language.all.collect { |language|
      [ language.language_short, language.id ] }
      show.input :author_id, as: :select, collection: Author.all.collect { |author| [ author.full_name, author.age,
      author.gender_short, author.biography, author.id ] }
      show.input :title
      show.input :genre_id, as: :select, collection: Genre.all.collect { |genre| [ genre.genre, genre.id ] }
      show.input :book_type
      show.input :year_released
      show.input :price
    end

    show.actions
  end
end

Book模型代码

class Book < ApplicationRecord
  # 验证所有字段非空
  validates :title, :page_count, :book_type, :year_released, :price, presence: true
  # 验证标题唯一
  validates :title, uniqueness: true
  # 关联父表与子表
  # has_and_belongs_to_many :genres
  belongs_to :language
  belongs_to :author
  has_many :purchases

  def self.ransackable_associations(auth_object = nil)
    [ "author", "genres", "language", "purchases" ]
  end

  def self.ransackable_attributes(auth_object = nil)
    [ "author_id", "book_type", "created_at", "genre_id", "id", "language_id", "page_count", "price", "title", "updated_at", "year_released" ]
  end
end

创建Book时的服务器日志

Started POST "/admin/books" for 127.0.0.1 at 2025-04-10 14:45:29 -0500
Processing by Admin::BooksController#create as HTML
  Parameters: {"authenticity_token" => "[FILTERED]", "book" => {"language_id" => "3", "author_id" => "6", "title" => "Captain Underpants", "genre_id" => "8", "book_type" => "Physical", "year_released" => "1997", "price" => "9.99"}, "commit" => "Create Book"}
  AdminUser Load (0.2ms)  SELECT "admin_users".* FROM "admin_users" WHERE "admin_users"."id" = 3 ORDER BY "admin_users"."id" ASC LIMIT 1 /*action='create',application='ECommerce',controller='books'*/
  TRANSACTION (0.1ms)  BEGIN immediate TRANSACTION /*action='create',application='ECommerce',controller='books'*/
  Book Exists? (2.9ms)  SELECT 1 AS one FROM "books" WHERE "books"."title" = 'Captain Underpants' LIMIT 1 /*action='create',application='ECommerce',controller='books'*/
  Language Load (0.3ms)  SELECT "languages".* FROM "languages" WHERE "languages"."id" = 3 LIMIT 1 /*action='create',application='ECommerce',controller='books'*/
  Author Load (0.1ms)  SELECT "authors".* FROM "authors" WHERE "authors"."id" = 6 LIMIT 1 /*action='create',application='ECommerce',controller='books'*/
  TRANSACTION (0.1ms)  ROLLBACK TRANSACTION /*action='create',application='ECommerce',controller='books'*/
  Rendering /home/segern/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/activeadmin-3.3.0/app/views/active_admin/resource/new.html.arb
  Language Load (0.2ms)  SELECT "languages".* FROM "languages" /*action='create',application='ECommerce',controller='books'*/
  ↳ app/admin/books.rb:7:in 'Enumerable#collect'
  Author Load (0.7ms)  SELECT "authors".* FROM "authors" /*action='create',application='ECommerce',controller='books'*/
  ↳ app/admin/books.rb:9:in 'Enumerable#collect'
  Genre Load (0.3ms)  SELECT "genres".* FROM "genres" /*action='create',application='ECommerce',controller='books'*/
  ↳ app/admin/books.rb:12:in 'Enumerable#collect'
  Rendered /home/segern/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/activeadmin-3.3.0/app/views/active_admin/resource/new.html.arb (Duration: 57.9ms | GC: 1.0ms)
Completed 200 OK in 89ms (Views: 58.0ms | ActiveRecord: 4.5ms (7 queries, 0 cached) | GC: 1.7ms)


Started GET "/favicon.ico" for 127.0.0.1 at 2025-04-10 14:45:29 -0500

ActionController::RoutingError (No route matches [GET] "/favicon.ico"):

问题分析与解决方案

问题根源

从日志可见事务执行了ROLLBACK,说明模型验证未通过。检查Book模型的验证规则:

  • validates :title, :page_count, :book_type, :year_released, :price, presence: true 要求这些字段不能为空
  • 表单提交的参数中缺失page_count字段,触发非空验证失败,导致记录无法保存,事务回滚。
  • 另外,author_id的select集合返回了多元素数组([author.full_name, author.age, author.gender_short, author.biography, author.id]),会导致下拉选项结构异常,可能引发参数解析问题。

解决方案

  1. 在Active Admin表单中添加page_count输入字段,确保用户可填写该值:
    修改admin/books.rb的form部分:
form do |show|
  show.inputs "Details" do
    show.input :language_id, as: :select, collection: Language.all.collect { |language| [ language.language_short, language.id ] }
    show.input :author_id, as: :select, collection: Author.all.collect { |author| [ author.full_name, author.id ] }
    show.input :title
    show.input :page_count # 新增page_count输入项
    show.input :genre_id, as: :select, collection: Genre.all.collect { |genre| [ genre.genre, genre.id ] }
    show.input :book_type
    show.input :year_released
    show.input :price
  end

  show.actions
end
  1. 修正author_id的select集合,仅保留显示文本和值两个元素([author.full_name, author.id]),避免参数异常。

修改后重新提交表单,即可正常创建Book记录并触发302重定向到书籍列表。


内容的提问来源于stack exchange,提问作者Segern Jose Monterola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:14:49