0

我编写了一个应用程序来获取last_insurance值,sum但在我看来,我得到了“nil:NilClass 的未定义方法`total'”。

我的桌子是:

|policies|
  ID    POLICY_NUM  DELETED    STATE    POLICY_BUSINESS_UNIT_ID
   1    1234           0         0            1
   2    5678           0         1            1
   3    3444           0         0            2           
   4    4577           0         1            2 

|insurances|
  ID    POLICY_ID   NET_INSURANCE   TYPE_MONEY 
   1        1               300        1
   2        1               400        2
   3        1               100        1
   4        2               400        1
   5        2               800        2
   6        3               100        1
   7        3               400        2
   8        4               800        2
   9        2               900        1

我有很多信息,但这是很少的描述:

http://sqlfiddle.com/#!2/ed2dd/4

这是我的模型:

 class Policy < ActiveRecord::Base
   has_many :insurances
 end

 class Insurance < ActiveRecord::Base
   belongs_to :policy
 end

这是我的控制器:

class PolicyController < ApplicationController
     def calculator

        @business = PolicyBusinessUnit.find(:all)

        @euros = Policy.find_by_sql(["SELECT i1.type_money, SUM( i1.net_insurance ) total
        FROM (SELECT MAX( id ) id FROM insurances GROUP BY policy_id)i2
        JOIN insurances i1 USING ( id ) 
        JOIN policies p ON p.id = i1.policy_id
        WHERE i1.type_money = 2 
        AND p.deleted= 0 
        AND p.policy_business_unit_id = ? AND p.state = ?
        GROUP BY i1.type_money" ,params[:busi].to_i,params[:state].to_i  ])
     end
end

这是我在组合框中显示我的状态的视图:

  <% form_tag :controller=>"policy",:action=>"calculator" do %>
      Business:
      <%= select_tag "busi",options_for_select(@business.collect {|t| [t.name.to_s,t.id]},  params[:busi].to_i ) %>

      Status:
      <%= select_tag "state",options_for_select([ ["OK",0],["CANCEL",1] ],params[:state].to_i) %>
      <%= submit_tag "SEARCH", :name => nil %>
  <% end %>

  Sum Euros:
  <input id="euros" readonly="readonly" value="<%= @euros[0].total"/>

我收到这条消息:

  undefined method `total' for nil:NilClass

但是,当我尝试这个时,当我不使用它时它工作正常params[busi]

    @dolares= Policy.find_by_sql(["SELECT sum(i1.net_insurance) total 
        FROM (SELECT max(id) id FROM insurances GROUP BY policy_id)i2
        JOIN insurances i1 USING (id)
        JOIN policies p ON p.id = i1.policy_id
        WHERE i1.type_money = 2 
        AND p.deleted= 0 
        AND p.policy_business_unit_id = 2 AND p.state = ?
        GROUP BY i1.type_money" , params[:state].to_i  ])

另一件事,当我在这里删除total并使用带有 2 个参数的控制器时:

    @dolares= Policy.find_by_sql(["SELECT sum(i1.net_insurance) total 
        FROM (SELECT max(id) id FROM insurances GROUP BY policy_id)i2
        JOIN insurances i1 USING (id)
        JOIN policies p ON p.id = i1.policy_id
        WHERE i1.type_money = 2 
        AND p.deleted= 0 
        AND p.policy_business_unit_id = ? AND p.state = ?
        GROUP BY i1.type_money" , params[:busi].to_i,params[:state].to_i  ])

   <input id="euros" readonly="readonly" value="<%= @euros[0]"/>

我得到了#<Policy:0x7f41d09909d0>

之后我再次添加了“总计”,我得到了没有问题的价值

   <input id="euros" readonly="readonly" value="<%= @euros[0].total"/>

也许我需要添加一个条件?怎么了?

4

3 回答 3

0

毫无疑问,您正在运行的 SQL 代码没有返回params[:state]. 您可以通过直接从控制台运行 SQL 来测试这一点。

作为记录,您可以使用查询 API 执行相同的查询:

sub_query = Insurance.group(:policy_id).
                      select('MAX(insurances.id)').to_sql
Insurance.joins(:policy).where("insurances.id IN (#{sub_query})").
                         where(type_money: 2).
                         where(policies: {deleted: 0, 
                                          policy_business_unit_id: params[:busi].to_i,
                                          state: params[:state].to_i }).
                         sum(:net_insurance)
于 2013-10-31T19:54:56.067 回答
0

好吧,@carlitos 根据您的上一版本,您得到 nil 值,因为它的值为 0。因此,要不显示错误,您需要尝试以下操作:

<input id="euros" readonly="readonly" value="<%= @euros[0].try(:total)"/>

这将隐藏错误并在总和为零时显示 0。

于 2013-10-31T21:48:26.007 回答
-1

一旦你解决了你的nil问题,你可能会发现你遇到了第二个问题:因为你find_by_sql,你可能无法获得 Active Record 绑定的便利。从多个表加入并创建复杂的 SQL 时,我遇到了这个问题。

尝试:

@euros[0]['total']

我不能花时间重新实现您的情况来测试这一点,但我认为 SQL 方法对结果使用哈希结构。如果没有,只需打印以调试/检查对象以查看其结构并确定如何引用它。

在最坏的情况下,您可能需要说:

@euros[0][1]

因为total是 SQL 结果中每一行的第二项。

于 2013-10-31T19:53:05.653 回答