Module: AscDesc::ModelAdditions

Defined in:
lib/asc_desc/model_additions.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_sym, *arguments, &block) ⇒ Object (private)

The **dynamic order_by mechanism** is built the same way as the dynamic finders present from the beginning of Ruby On Rails and allows to easely write the order clause for ActiveRecord queries.

using a column as part of the method name

Candy.where(:sugar => true).order_by_name

using a column and a sort direction (asc|desc) as part of the method name

Candy.where(:sugar => true).order_by_name_asc
Candy.where(:sugar => true).order_by_name_desc

using multiple columns as part of the method name

Candy.where(:sugar => true).order_by_classification_and_name
Candy.where(:sugar => true).order_by_classification_and_name_and_sugar

using multiple columns and sort directions (asc|desc) as part of the method name

Candy.where(:sugar => true).order_by_classification_asc_and_name_desc
Candy.where(:sugar => true).order_by_classification_desc_and_name_asc
Candy.where(:sugar => true).order_by_classification_asc_and_name_desc_and_sugar_asc

using multiple columns with or without sort direction (asc|desc) as part of the method name

Candy.where(:sugar => true).order_by_classification_and_name_desc
Candy.where(:sugar => true).order_by_classification_desc_and_name


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/asc_desc/model_additions.rb', line 101

def method_missing(method_sym, *arguments, &block)
  # the first argument is a Symbol, so we need to_s it if you want to match the pattern
  if method_sym.to_s =~ /^order_by_([_a-zA-Z]\w*)$/
    columns = $1.split('_and_').map do |column|
      if column.ends_with?('_asc')
        "#{column[0..-5]} ASC"
      elsif column.ends_with?('_desc')
        "#{column[0..-6]} DESC"
      else
        "#{column} ASC" # always use explicit sort direction
      end
    end
    self.order(columns)
  else
    super
  end
end

Instance Method Details

#asc(*args) ⇒ Object Also known as: ascending, ascending_order

Call asc on an ActiveRecord object or on an ActiveRecord::Relation object to sort the column(s) in an ascending way.

using a symbol for the name of the column

Candy.where(:sugar => true).asc(:name)

using a string for the name of the column

Candy.where(:sugar => true).asc('name')

using multiple parameters to specify more than one column for the sort clause

Candy.where(:sugar => true).asc(:classification, :name)

using an array to pass mutliple argument

Candy.where(:sugar => true).asc([:classification, :name])

using a string to specify more than one column for the sort clause

Candy.where(:sugar => true).asc('classification, name')

without argument, the method generates a sort by id (custom primary key supported)

SELECT "candies".* FROM "candies" ORDER BY id ASC
Candy.where(:sugar => true).asc

the method is chainable

Candy.where(:sugar => true).asc(:classification).asc(:name)


29
30
31
# File 'lib/asc_desc/model_additions.rb', line 29

def asc(*args)
  self.order AscDesc.format_order_clause(*(args.presence || [self.primary_key]) << AscDesc::ASC)
end

#desc(*args) ⇒ Object Also known as: descending, descending_order

Call desc on an ActiveRecord object or on an ActiveRecord::Relation object to sort the column(s) in a descending way.

using a symbol for the name of the column

Candy.where(:sugar => true).desc(:name)

using a string for the name of the column

Candy.where(:sugar => true).desc('name')

using multiple parameters to specify more than one column for the sort clause

Candy.where(:sugar => true).desc(:classification, :name)

using an array to pass mutliple argument

Candy.where(:sugar => true).desc([:classification, :name])

using a string to specify more than one column for the sort clause

Candy.where(:sugar => true).desc('classification, name')

without argument, the method generates a sort by id (custom primary key supported)

SELECT "candies".* FROM "candies" ORDER BY id DESC
Candy.where(:sugar => true).desc

the method is chainable

Candy.where(:sugar => true).desc(:classification).desc(:name)


61
62
63
# File 'lib/asc_desc/model_additions.rb', line 61

def desc(*args)
  self.order AscDesc.format_order_clause(*(args.presence || [self.primary_key]) << AscDesc::DESC)
end

#order_by(*args) ⇒ Object

a call to order_by just acts like the standard built-in “order” method (alias)

Candy.where(:sugar => true).order_by('classification ASC, name ASC')


71
72
73
# File 'lib/asc_desc/model_additions.rb', line 71

def order_by(*args)
  self.order(*args)
end