代码之家  ›  专栏  ›  技术社区  ›  jvillian

有没有更惯用的方法来实现我的“检查计数”方法?

  •  0
  • jvillian  · 技术社区  · 7 年前

    我的问题是是否有一种更简单或更惯用的方法来实现 check_count 我的方法 Deposit 班级?

    这里是(长)上下文。在我目前的项目中,我有课程 LineItem :

    # == Schema Information
    #
    # Table name: line_items
    #
    #  id                 :integer          not null, primary key
    #  customer_id        :integer          not null
    #  item_type_id       :integer          not null
    #  amount_cents       :integer          not null
    #  amount_currency    :string           not null
    #  check_number       :string
    #  lineable_type      :string 
    #  lineable_id        :integer
    #  created_at         :datetime         not null
    #  updated_at         :datetime         not null
    #
    class LineItem < ActiveRecord::Base
    
      belongs_to :lineable, polymorphic: true
    
      validates :lineable_type,
                :lineable_id,
                :customer_id,
                :item_type,
                :amount_cents,
                :amount_currency,
                presence: true
    
      validates :check_number, presence: true, if: :check?
    
      enum item_type: {
        check:  0,
        cash:   1
      }
    
      def check?; item_type == :check end
    
    end
    

    存包处 :

    class Deposit < ActiveRecord::Base
    
      has_many  :line_items,
                as: :lineable,
                dependent: :destroy
    
      def check_items
        line_items.where(item_type: LineItem.item_types['check'])
      end
    
      def check_count
        check_items.
          group_by(&:customer_id).
          transform_values{|v| v.map(&:check_number).uniq.count}.
          values.
          sum
      end
    
    end
    

    所以,如果在我的 line_items 表,我有(省略不相关的部分):

    --------------------------------------------------------------------------------
    | id | customer_id | item_type_id | check_number | lineable_type | lineable_id |
    --------------------------------------------------------------------------------
    | 1  | 1           | 0            | 9989         | 'Deposit'     | 1           |
    | 2  | 1           | 0            | 9989         | 'Deposit'     | 1           |
    | 3  | 2           | 0            | 9989         | 'Deposit'     | 1           |
    --------------------------------------------------------------------------------
    

    我能做到:

    Deposit.find(1).check_count
     => 2
    

    这是正确的结果。

    检查计数 我觉得这个方法很笨拙。我是不是找不到更干净的方法?

    我使用的是Rails4.2.8和Ruby2.5.1。

    1 回复  |  直到 7 年前
        1
  •  1
  •   mpospelov    7 年前

    据我所知,您正在汇总每个客户的所有唯一支票号码。

    你可以用 GROUP BY SQL的功能。这是一个 good example 如何进行双栏分组。 所以为了在ActiveRecord(AR)中获得相同的效果,您可以这样做。

      def check_count
        check_items.group(:customer_id, :check_number).count.count
      end
    

    注: 由于您对许多这样的团体感兴趣,我们打电话来 #count 2次。 在第一次调用时,将调用ar关系,结果为

    check_items.group(:customer_id, :check_number).count #=> {[1, '9989'] => 2, [2, '9989'] => 1}
    

    第二个计数调用将计算组数

    {[1, '9989'] => 2, [2, '9989'] => 1}.count # => 2