My question is whether there is a simpler or more idiomatic way to implement the check_count
method for my Deposit
class?
Here's the (long) context. In my current project, I have the classes 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
and Deposit
:
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
So, if in my line_items
table, I have (omitting the irrelevant bits):
--------------------------------------------------------------------------------
| 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 |
--------------------------------------------------------------------------------
I can do:
Deposit.find(1).check_count
=> 2
Which is the correct result.
That check_count
method seems clunky to me. Am I missing some cleaner way of doing this?
I'm using rails 4.2.8 and ruby 2.5.1.