ActiveRecord sum和pluck方法返回奇怪的值

myo*_*yoo 6 activerecord ruby-on-rails

我有Order模型并Order.all在下面返回.

[
[0] #<Order:0x007f9d9e236de0> {
              :id => 15,
         :user_id => 2,
       :artist_id => nil,
      :address_id => 18,
         :paid_at => nil,
    :payment_type => "bank",
            :guid => "c8e22764774adc6825348b8874b581e8",
      :created_at => Mon, 24 Aug 2015 19:42:09 JST +09:00,
      :updated_at => Mon, 24 Aug 2015 19:45:38 JST +09:00,
      :ordered_at => Mon, 24 Aug 2015 19:45:37 JST +09:00,
           :total => 43890
},
[1] #<Order:0x007f9d9e2367a0> {
              :id => 12,
         :user_id => 2,
       :artist_id => nil,
      :address_id => 18,
         :paid_at => nil,
    :payment_type => "bank",
            :guid => "274b4a8653395023125a4724139efc09",
      :created_at => Mon, 24 Aug 2015 19:10:38 JST +09:00,
      :updated_at => Mon, 24 Aug 2015 19:41:25 JST +09:00,
      :ordered_at => Mon, 24 Aug 2015 19:41:22 JST +09:00,
           :total => 48689
},
[2] #<Order:0x007f9d9e236318> {
              :id => 11,
         :user_id => 2,
       :artist_id => nil,
      :address_id => 14,
         :paid_at => Mon, 24 Aug 2015 19:10:38 JST +09:00,
    :payment_type => "credit_card",
            :guid => "b075f4a6f31c32942152f7d50d2bd098",
      :created_at => Mon, 24 Aug 2015 19:03:39 JST +09:00,
      :updated_at => Mon, 24 Aug 2015 19:10:38 JST +09:00,
      :ordered_at => Mon, 24 Aug 2015 19:10:38 JST +09:00,
           :total => 5010
},
[3] #<Order:0x007f9d9e235e40> {
              :id => 10,
         :user_id => nil,
       :artist_id => nil,
      :address_id => nil,
         :paid_at => nil,
    :payment_type => nil,
            :guid => "916ff17977cb176c5e5740faab92a08c",
      :created_at => Sat, 22 Aug 2015 19:30:38 JST +09:00,
      :updated_at => Sat, 22 Aug 2015 19:30:38 JST +09:00,
      :ordered_at => nil,
           :total => 0
},
[4] #<Order:0x007f9d9e2356c0> {
              :id => 9,
         :user_id => 1,
       :artist_id => nil,
      :address_id => 9,
         :paid_at => nil,
    :payment_type => "bank",
            :guid => "a4f1dd11ad035d1747a37776b062021f",
      :created_at => Sat, 22 Aug 2015 19:30:04 JST +09:00,
      :updated_at => Tue, 01 Sep 2015 00:00:09 JST +09:00,
      :ordered_at => Sat, 22 Aug 2015 00:00:00 JST +09:00,
           :total => 5010
},
[5] #<Order:0x007f9d9e2342c0> {
              :id => 8,
         :user_id => 1,
       :artist_id => nil,
      :address_id => 9,
         :paid_at => Thu, 20 Aug 2015 19:30:04 JST +09:00,
    :payment_type => "credit_card",
            :guid => "b816503b6b95d35455262cd4d8b9e822",
      :created_at => Sat, 22 Aug 2015 19:30:04 JST +09:00,
      :updated_at => Sat, 22 Aug 2015 19:30:04 JST +09:00,
      :ordered_at => Wed, 19 Aug 2015 19:30:04 JST +09:00,
           :total => 0
}
Run Code Online (Sandbox Code Playgroud)

]

但是,Order.sum(:total)退货

Order.sum(:total)
(0.4ms)  SELECT SUM("orders"."total") FROM "orders"
12000
Run Code Online (Sandbox Code Playgroud)

Order.pluck(:total)返回

Order.pluck(:total)
CACHE (0.0ms)  SELECT "orders"."total" FROM "orders"  ORDER BY   "orders"."created_at" DESC
[
    [0] nil,
    [1] nil,
    [2] nil,
    [3] nil,
    [4] 2000,
    [5] 10000
]
Run Code Online (Sandbox Code Playgroud)

所以发生了什么事?我怎样才能获得正确的价值?

非常感谢.

我有默认范围,但只有订单,

   default_scope { order(created_at: :desc) }
Run Code Online (Sandbox Code Playgroud)

.这会影响这个问题吗?

这是'Order.all'查询.

Order Load (1.0ms) SELECT "orders".* FROM "orders" ORDER BY "orders"."created_at" DESC 
Item Load (0.4ms) SELECT "items".* FROM "items" WHERE "items"."order_id" = $1 [["order_id", 20]] 
Flower Load (0.7ms) SELECT "flowers".* FROM "flowers" WHERE "flowers"."type" IS NULL AND "flowers"."item_id" = $1 ORDER BY "flowers"."created_at" ASC LIMIT 1 [["item_id", 8]]   
Run Code Online (Sandbox Code Playgroud)

Order.all.map(&:total) 回报

[ [ 0] 43890, [ 1] 48689, [ 2] 5010, [ 3] 0, [ 4] 5010, [ 5] 0 ] 
Run Code Online (Sandbox Code Playgroud)

抱歉延迟回复......

这是我对orders.html.erb的结果,我只使用myapp_development和myapp_test数据库.

Order.count 6
Order.sum(:total)   12,000
Order.pluck(:total) [nil, nil, 2000, 10000, nil, nil]
Order.all.map(&:total)  [0, 5010, 0, 0, 16110, 0]
#<Order id: 6, user_id: 1, artist_id: nil, address_id: nil, paid_at: nil, payment_type: nil, guid: "a6471c15680a0fbcd3f515a1bdf83566", created_at: "2015-09-02 07:24:37", updated_at: "2015-09-02 07:24:37", ordered_at: nil, total: nil, conveni_name: nil, conveni_code: nil, invoice_id: nil>

#<Order id: 5, user_id: 1, artist_id: nil, address_id: 14, paid_at: "2015-09-02 07:24:36", payment_type: 0, guid: "b68989c73bc0af34e3eef56abbcb306c", created_at: "2015-09-01 08:58:07", updated_at: "2015-09-02 07:24:36", ordered_at: "2015-09-02 07:24:36", total: nil, conveni_name: nil, conveni_code: nil, invoice_id: nil>

#<Order id: 4, user_id: 1, artist_id: nil, address_id: 1, paid_at: nil, payment_type: 2, guid: "1863cc6f2884b88598c4524d564b8a4a", created_at: "2015-09-01 06:07:52", updated_at: "2015-09-01 06:07:52", ordered_at: "2015-08-31 15:00:00", total: 2000, conveni_name: nil, conveni_code: nil, invoice_id: nil>

#<Order id: 3, user_id: 1, artist_id: nil, address_id: 1, paid_at: "2015-08-30 06:07:52", payment_type: 0, guid: "a6f7e22fc9ea8bdccdbdcbb00d9ea250", created_at: "2015-09-01 06:07:52", updated_at: "2015-09-01 06:07:52", ordered_at: "2015-08-29 06:07:52", total: 10000, conveni_name: nil, conveni_code: nil, invoice_id: nil>

#<Order id: 2, user_id: 1, artist_id: nil, address_id: 11, paid_at: "2015-09-01 08:58:06", payment_type: 0, guid: "f29dd23315078fce2e5b38e16d027c45", created_at: "2015-09-01 06:06:33", updated_at: "2015-09-01 08:58:06", ordered_at: "2015-09-01 08:58:06", total: nil, conveni_name: nil, conveni_code: nil, invoice_id: nil>

#<Order id: 1, user_id: nil, artist_id: nil, address_id: nil, paid_at: nil, payment_type: nil, guid: "6f2ffd0e8ba491fba10d69b73e717384", created_at: "2015-09-01 03:08:44", updated_at: "2015-09-01 03:08:44", ordered_at: nil, total: nil, conveni_name: nil, conveni_code: nil, invoice_id: nil>
Run Code Online (Sandbox Code Playgroud)

dim*_*ura 6

您提供的信息是矛盾的.

我想你看看不同的数据库.

让我解释为什么我这么认为.

事实#1基于Order.all输出,我们有:

#<Order id: 15, total: 43890.0>
#<Order id: 12, total: 48689.0>
#<Order id: 11, total: 5010.0>
#<Order id: 10, total: 0.0>
#<Order id: 9,  total: 5010.0>
#<Order id: 8,  total: 0.0>
Run Code Online (Sandbox Code Playgroud)

total这里的属性与数据库中的内容相同.即使您在Order模型中定义了具有相同名称的方法,该属性也不应受其影响.

事实#2根据Order.pluck(:total)输出我们有:

#<Order id: 15, total: nil>
#<Order id: 12, total: nil>
#<Order id: 11, total: nil>
#<Order id: 10, total: nil>
#<Order id: 9,  total: 2000>
#<Order id: 8,  total: 10000>
Run Code Online (Sandbox Code Playgroud)

同样,total这里的属性与数据库中的内容相同.同样,它不受模型中定义的方法的影响.

现在我们看到事实1事实2相矛盾.我几乎肯定你在这里看不同的数据库.

确保您不会产生矛盾结果的最佳方法是创建一个包含此内容的新页面:

<!-- orders.html.erb -->

<table>
  <tr>
    <td>Order.count</td>
    <td><%= Order.count %></td>
  </tr>
  <tr>
    <td>Order.sum(:total)</td>
    <td><%= number_with_delimiter Order.sum(:total) %></td>
  </tr>
  <tr>
    <td>Order.pluck(:total)</td>
    <td><%= Order.pluck(:total) %></td>
  </tr>
  <tr>
    <td>Order.all.map(&amp;:total)</td>
    <td><%= Order.all.map(&:total) %></td>
  </tr>
</table>

<% Order.all.each do |o| %>
  <p>
    <code><%= o.inspect %></code>
  </p>
<% end %>
Run Code Online (Sandbox Code Playgroud)

并提供此页面的输出以供进一步探索.

基本上我要求的是:

  1. 检查您没有使用两个不同的数据库
  2. 如果#1无用,请使用给定的ERB模板创建一个新操作并共享它的输出.


小智 4

如果Order.pluck(:total)返回的内容与 不同Order.all.map(&:total),则“total”方法可能在某处定义,从而覆盖列属性方法。您可以通过以下方式检查此方法的源文件名和行:

Order.new.method(:total).source_location
Run Code Online (Sandbox Code Playgroud)

应该参考一下activerecord-4.2.4/lib/active_record/attribute_methods.rb。如果没有,那么这就是您不小心覆盖了 ActiveRecord 方法的地方。