Dynamic calculations in Rails

Asked

Viewed 790 times

4

I hope you can help me.

I have a Rated who owns evaluations, have several calculations to determine whether or not it will pass an evaluation step. For example one of these calculations is calcula_pontuacao_minima()

#Cálculo definido pela resolução 1
def calcula_pontuacao_minima(avaliado)
  calcula_porcentagem(avaliado.avaliacoes)>60 #onde esta soma todas as notas do avaliado e retorna a porcentagem de aproveitamento
end

My problem here is the appearance of resolutions that alter the calculation, so that all the evaluated before that resolution, must be evaluated for calculations old and new evaluated shall be classified using calculations changed. For example a resolution changes the minimum value to 50%

#Cálculo definido pela resolução 2
def calcula_pontuacao_minima(avaliado)
  calcula_porcentagem(avaliado.avaliacoes)>50 #onde esta soma todas as notas do avaliado e retorna a porcentagem de aproveitamento
end

And if in a future they still change to instead of taking the percentage, the minimum value is compared to the total value of the ratings

#Cálculo definido pela resolução 3
def calcula_pontuacao_minima(avaliado)
  calcula_total(avaliado.avaliacoes)>70 #onde esta soma todas as notas do avaliado onde o máximo é 120
end

So for example Evaluated which had their evaluations carried out before the date X that defined the resolution 2, will be evaluated by the first calculation after that date X will be evaluated by the second calculus, and after the date Y where the resolution 3, will be evaluated by the third calculation.

Any idea how this can be fixed? It would be a good idea to store the database-level calculations?

  • 1

    All those evaluated before resolution... That were created before resolution or there is some other date field relating to the creation of resolution?

  • @Felipeavelar there are fields that will be created after resolution =\

  • 1

    Then I’ll add how I would, then you see if the answer fits what you want.

  • 1

    The calculations will change with what constancy? The user needs to change them or it can be something done by the developer?

  • @Alextakitani good, utopically the user should change, but I think it is impossible to create something at this level. So it’s a good solution where dev can make this change in a Ruby Like way, it’s already the solution I’m looking for.

  • 1

    It is not utopian, with Val is easy to do even, as long as you take care not to let the user enter with dangerous data.

  • The concept of Strategy exists in Ruby?

Show 2 more comments

1 answer

2

The resolution I would make would be to use a created field (which according to your comment will be created later) or the created_at and based on the resolution creation date (considering you have a table of resolutions or the dates they were), I would use only the creation dates of resolutions, considering, for example, a date X for resolution 1, a date Y for resolution 2 and Z for resolution 3. If you want to run the method for each evaluated, this would be:

def calcula_pontuacao_minima(avaliado)
  if(avaliado.created_at < Y)
    return calcula_total(avaliado.avaliacoes) > 60
  elsif (avaliado.created_at >= Y && avaliado.created_at < Z)
    return calcula_total(avaliado.avaliacoes) > 50
  else
    return calcula_total(avaliado.avaliacoes) > 70
  end
end

In case you want to do for everyone at once (what I advise), the ideal would be to do as follows:

def calcula_pontuacao_minima
  resultado = []
  Avaliado.where('created_at < ?', Y).all.each do |avaliado|
    a.push(calcula_total(avaliado.avaliacoes) > 60)
  end
  Avaliado.where('created_at >= ? AND created_at < ?', Y, Z).all.each do |avaliado|
    a.push(calcula_total(avaliado.avaliacoes) > 60)
  end
  Avaliado.where('created_at >= ?', Z).all.each do |avaliado|
    a.push(calcula_total(avaliado.avaliacoes) > 60)
  end
  return a
end

I don’t know if this is what you want, but it’s what I’ve been able to infer from your question.

  • 2

    Thanks for the @Felipe reply, good. This is one of the factors I wanted to avoid, because imagine that during the system 50 resolutions are created? then have a Where for each resolution. My doubt was only if there is a more DRY way to do it. Not existing your answer is valid.

  • In this case, you could put a table only for resolutions and use them in a each or pass a list of resolution dates and do within a each for every element of that list. These are the forms I see...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.