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

Rails使用PostgreSQL Money类型时显示0.0而非真实数值

Hey there! Let's troubleshoot why those calculated Money fields in your Orders table are stuck showing 0.0 instead of their actual values. I’ve dealt with similar gotchas when using database triggers alongside Rails’ ActiveRecord, so here are the most common fixes to walk through:

1. Rails is using cached values instead of fresh database data

Since your triggers update the fields directly in the database, ActiveRecord might still hold onto the old (initial 0.0) values it loaded when the order object was first fetched. Try these quick checks:

  • In your Rails console, fetch an order and call reload on it before accessing the fields:
    order = Order.find(your_order_id)
    puts order.subtotal # Might show 0.0
    order.reload
    puts order.subtotal # Should now show the real value if the database has it
    
  • If that works, make sure to add reload in your controller before serializing the order for the API response:
    def show
      @order = Order.find(params[:id]).reload
      render json: @order
    end
    

2. Your Money type configuration is mismatched with the trigger’s target field

If you’re using the money-rails gem (super common for Money types in Rails), double-check your Orders model setup:

  • By default, money-rails stores monetary values as integer *_cents fields (e.g., subtotal_cents) and creates a virtual Money object for the subtotal attribute. If your trigger is updating the subtotal decimal field instead of subtotal_cents, Rails won’t pick up the change.
  • Verify your model has the correct monetize calls:
    class Order < ApplicationRecord
      # If your trigger updates subtotal_cents (integer)
      monetize :subtotal_cents, :fee_cents, :total_cents
    
      # OR if your trigger updates subtotal (decimal)
      monetize :subtotal, :fee, :total, as: :money
    end
    
  • Cross-check your database schema to confirm which fields the trigger is modifying (run rails db:migrate:status or look at your migration files).

3. The trigger itself isn’t working correctly

Before blaming Rails, confirm the trigger is actually writing the right values to the database:

  • Run a direct SQL query in your database console to check the raw values:
    SELECT subtotal, fee, total FROM orders WHERE id = your_order_id;
    
  • If the query returns 0.0 here, your trigger logic is the issue. Double-check the trigger’s calculation rules (e.g., is it referencing the right columns from join tables, or is there a typo in the arithmetic?).

4. Your API serializer is mishandling the Money object

If the values look correct in the Rails console but show 0.0 in the API response, your serializer might not be properly converting the Money object to a numeric value:

  • If using ActiveModel::Serializers, adjust your serializer to explicitly convert the Money field:
    class OrderSerializer < ActiveModel::Serializer
      attributes :id, :subtotal, :fee, :total
    
      def subtotal
        object.subtotal.to_f # or to_s if you want a formatted string
      end
    
      # Repeat for fee and total
    end
    
  • For FastJSONAPI, use a custom attribute block to handle the conversion similarly.

Start with the first check (reloading the object) since it’s the quickest win, then work your way down based on what you find.

内容的提问来源于stack exchange,提问作者Ricardo Villagrana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:31:47