Neil Neil - 2 months ago 9
Ruby Question

Scope Change from Pure String Syntax to Hash Syntax

I have the following scope within a model:

class Office < ApplicationRecord
belongs_to :money_pot
has_one :fiscal_year, through: :money_pot
has_one :money_type, through: :money_pot

scope :order_by_fiscal_year_and_money_type, -> {
joins(money_pot: [:fiscal_year, :money_type])
.order("fiscal_years.end_date desc, money_types.short_name")}
end


This scope does work. However: I would like to switch from the "pure string" syntax to the "hash" syntax within that
order
clause. I am having trouble I think due to the fact that the
order
clause within the scope is on the associations.

Here is what I have tried but it didn't work:

scope :order_by_fiscal_year_and_grant_type, -> {
joins(money_pot: [:fiscal_year, :money_type])
.order(fiscal_years: {end_date: :desc}, money_types: {short_name: :asc})}


Here is the error it returns:


Direction "{:end_date=>:desc}" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]


I have looked at the ordering section and the hash conditions section of the Active Record Query Interface Rails Guides.

How can I convert this scope completely into the hash syntax?

Answer

The only way I have found to not using plain string is merge:

scope :order_by_fiscal_year_and_money_type, lambda {
  joins(money_pot: [:fiscal_year, :money_type])
    .merge(FiscalYears.order(end_date: :desc)
    .merge(MoneyType.order(:short_name)
}
Comments