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

Rails中使用Spree创建产品触发PG非空约束错误求解决方案

Fixing ActiveRecord::StatementInvalid (PG::NotNullViolation) in Spree with spree_globalize

Looks like you're hitting a classic issue with spree_globalize where product translatable attributes (like name) aren't being handled correctly. Let's break down the problem and fix it step by step:

Why This Happens

When using spree_globalize, attributes like name, description, and meta fields get moved from the main spree_products table to a separate spree_product_translations table (one row per locale). Your error shows the app is still trying to insert a null value into the name column of spree_products—which has a not-null constraint—because either:

  • The migration to remove name from spree_products wasn't run, or
  • The spree_globalize configuration for your Product model is missing.

Step 1: Fix the spree_globalize Setup

First, make sure your Product model is properly configured to use translations. Check for an initializer (usually config/initializers/spree_globalize.rb) with code like this:

Spree::Product.class_eval do
  translates :name, :description, :meta_description, :meta_keywords
end

If this file doesn't exist, create it. This tells Spree to store those attributes in the translations table instead of the main products table.

Step 2: Run the Required Migrations

spree_globalize adds its own migrations to adjust the database schema. Run these commands to install and execute them:

bundle exec rake railties:install:migrations FROM=spree_globalize
bundle exec rake db:migrate

These migrations will drop the name (and other translatable) columns from spree_products and create the spree_product_translations table where those attributes will live.

Step 3: Fix the "Missing spree_globalize" Error

Uninstalling spree_globalize caused errors because your Spree admin (or custom code) depends on it. To revert that:

  1. Re-add the gem to your Gemfile (use the version compatible with your Spree release):
    gem 'spree_globalize', github: 'spree/spree_globalize' # or specify a version like '5.0.0'
    
  2. Run bundle install to reinstall it.
  3. Re-run the migrations from Step 2 to get the correct database structure back.

Step 4: Debug the Form Submission

Your log snippet shows weird encoding in the parameters ("utf8"=>"鉁�"), which might mean the form isn't submitting the translatable fields correctly. Ensure:

  • The admin product form is rendering locale-specific inputs (spree_globalize should add fields like name_en or name_fr depending on your locales).
  • You're filling out the name field for the active locale in the admin.
  • You haven't overridden the product form without including the translatable fields.

Step 5: Verify the Database Schema

Double-check that the name column is gone from spree_products. Run:

rails dbconsole
# In PostgreSQL, run:
\d spree_products

If name is still present, the migration didn't run. You can manually run the specific migration file (look for files starting with 201*_add_translations_to_spree_products.rb in db/migrate) or rollback and re-run all migrations if needed.


Quick Compatibility Check

Make sure your Spree version matches the spree_globalize version. For example, Spree 5.x uses spree_globalize 5.x, Spree 4.x uses 4.x, etc. Check the gem's GitHub README for exact compatibility info.

Content of the question originates from Stack Exchange, question author "authenticity_token"=>"v="

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:56:42