Rails & ActiveRecord - refactoring with multiple identical locations

I'm on Rails 5.

I need to deal with a rather complex query with several identical sentences:

::AllocatedBudget.joins(:account_code, :budget, account_code: [:place],
                          budget: [:fiscal_year, :budget_state])
                    .where(immeuble:            { id: place.id })
                    .where(situation_budget:    { codesituation: ['A', 'V']})
                    .where(plan_comptable:      { supprime: 'false' })
                    .where(budget:              { supprime: 'false'})
                    .where(situation_budget:    { supprime: 'false' })
                    .where(budget_previsionnel: { supprime: 'false' })
                    .where(exercice_comptable:  { supprime: 'false' })

You should know first that my models are connected to an old database with ugly names. I noticed that ActiveRecord needs usernames instead of model names to execute queries. I don’t know why, but it only works that way ... If anyone can explain what would be nice;)

My real question is: can I write it better? There is so much time when the sentence is "supprime =" false ".

Thank you so much!:)

+4
source share
2 answers

, " " AndrewSwerlick

module QueryObject
  class AllocatedBudgetQuery

    def self.call(filters = {}, relation = ::AllocatedBudget.all)
      new(filters, relation).tap(&:call)
    end

    # filter can have the key/value as follow (key are symbols) :
    # place_id/string
    # current_fiscal_year/boolean
    # budget_state/['A', 'V', '*']
    def initialize(filters = {}, relation = ::AllocatedBudget.all)
      @relation     = relation
      @filters      = filters
    end

    def call
      conditions = {
        budget_previsionnel: { supprime: 'false' },
        budget: { supprime: 'false' }
      }

      # place filter
      conditions = conditions.merge(immeuble: { id: @filters[:place_id] }) if @filters.key?(:place_id)

      # situation budget filter
      conditions = conditions.merge(situation_budget: { codesituation: @filters[:budget_state] }) if @filters.key?(:budget_state)

      # main extract
      @relation = @relation.joins(:account_code,
                                  account_code: [:place],
                                  budget: %i[fiscal_year budget_state])
                           .where(conditions)

      # current fiscal year filter
      @relation = @relation.where("#{Date.today.to_s} between exercice_comptable.datedebutexercice and exercice_comptable.datefinexercice") if @filters.key?(:current_fiscal_year)
    end
  end
end
0

  • , ruby ​​
  • where.

, - - .

same_conditions_list = [
  :plan_comptable, 
  :budget, 
  :situation_budget, 
  :budget_previsionnel, 
  :exercice_comptable
]

same_conditions_key_values = same_conditions_list.inject({}) do |conditions, condition|
  conditions[condition] = { supprime: 'false' }
  conditions
end   

same_conditions = Hash[same_conditions_key_values]      

all_conditions = same_conditions.merge({
  immeuble: { id: "place.id" }
})       

all_conditions

{
  :plan_comptable=>{:supprime=>"false"},
  :budget=>{:supprime=>"false"},
  :situation_budget=>{:supprime=>"false"},
  :budget_previsionnel=>{:supprime=>"false"},
  :exercice_comptable=>{:supprime=>"false"},
  :immeuble=>{:id=>"place.id"}
}

::AllocatedBudget.joins(:account_code, :budget, account_code: [:place],
                      budget: [:fiscal_year, :budget_state])
                  .where(all_conditions)
+1

Source: https://habr.com/ru/post/1690675/


All Articles