Rails中使用Spree创建产品触发PG非空约束错误求解决方案
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
namefromspree_productswasn't run, or - The
spree_globalizeconfiguration 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:
- 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' - Run
bundle installto reinstall it. - 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_enorname_frdepending 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="

