-
Couldn't load subscription status.
- Fork 8
Description
Hello, I'm trying to implement a collection snapshot for a model that records transactions between people and which have certain limits that when reached, issues some alerts. These are the models:
class Transaction
field :trx_type, type: String
field :date, type: Date
field :city, type: String
belongs_to :account # emits transaction
belongs_to :person # receives transaction
end
class Limit
field :limit_exceeded, type: Boolean, default: false
field :year, type: Integer
field :city, type: String
field :cycle_type
field :trx_tp, type: String
belongs_to :account
belongs_to :person
end
To make a long story short, the idea here is that we would calculate the sum of the accumulated transactions for a given account/person pair, but that limit can be yearly (using year field) or by city (using the city field). So if cycle_type is :per_year, we use the year field to group the transactions and do the mapping, otherwise if it is :per_city, we use the city field instead.
What I don't know is how to use one or the other field in the map method, using cycle_type to decide, which is a field on the Limit model, and not the Transaction model I'm mapping. Note that any account/person pair will have the corresponding Limit object already created so at the moment of building the map, that information is already available.
But, how could I use some conditional mapping or any decision when mapping, in order to use one field or the other so that I can build the correct mapping with the correct fields set? That way when reading the values from the snapshot I can query them correctly, given the account/person pair for which we want the to check the calculated limit.
Here's my current, still unfinished, snapshot code:
class CumulativeSnapshot
include Mongoid::CollectionSnapshot
document do
belongs_to :person, inverse_of: nil
belongs_to :account, inverse_of: nil
field :year, type: Integer
field :city, type: String
field :trx_type, type: String
field :sum, type: Integer
end
def build
map = <<-EOS
function() {
emit({ year: this['date'].getFullYear(), person_id: this['person_id'], account_id: this['account_id'], trx_type: this['trx_type'], city: this['city'] }, { sum: this['amount']['cents'] })
}
EOS
reduce = <<-EOS
function(key, values) {
var sum = 0;
values.forEach(function(value) {
sum += value['sum'];
});
return({ sum: sum });
}
EOS
Transaction.map_reduce(map, reduce).out(inline: 1).each do |doc|
collection_snapshot.insert_one(
person_id: doc['_id']['person_id'],
account_id: doc['_id']['account_id'],
city: doc['_id']['city'],
year: doc['_id']['year'],
trx_type: doc['_id']['trx_type'],
sum: doc['value']['sum']
)
end
end
Do you think there's a way of using the Limit#cycle_type on the map method to make a decision?
Otherwise, I was thinking of building 2 separate snapshots, one with the city field, and another snapshot with the year field, but wanted to check if there is any cleaner solution first, hence this question.
Thanks in Advance!