Story#112050051 - extend ransack to sort invoices by custom scopes

This commit is contained in:
Vladimir Krylov 2016-02-08 10:36:22 +02:00
parent 0ce6b84ddf
commit db6f78ede4
3 changed files with 54 additions and 2 deletions

View file

@ -11,6 +11,18 @@ class Invoice < ActiveRecord::Base
scope :unbinded, lambda {
where('id NOT IN (SELECT invoice_id FROM account_activities where invoice_id IS NOT NULL)')
}
scope :all_columns, ->{select("invoices.*")}
scope :sort_due_date_column, ->{all_columns.select("CASE WHEN invoices.cancelled_at is not null THEN
(invoices.cancelled_at + interval '100 year') ELSE
invoices.due_date END AS sort_due_date")}
scope :sort_by_sort_due_date_asc, ->{sort_due_date_column.order("sort_due_date ASC")}
scope :sort_by_sort_due_date_desc, ->{sort_due_date_column.order("sort_due_date DESC")}
scope :sort_receipt_date_column, ->{all_columns.includes(:account_activity).references(:account_activity).select(%Q{
CASE WHEN account_activities.created_at is not null THEN account_activities.created_at
WHEN invoices.cancelled_at is not null THEN invoices.cancelled_at + interval '100 year'
ELSE NULL END AS sort_receipt_date })}
scope :sort_by_sort_receipt_date_asc, ->{sort_receipt_date_column.order("sort_receipt_date ASC")}
scope :sort_by_sort_receipt_date_desc, ->{sort_receipt_date_column.order("sort_receipt_date DESC")}
attr_accessor :billing_email
validates :billing_email, email_format: { message: :invalid }, allow_blank: true

View file

@ -12,9 +12,9 @@
%th{class: 'col-xs-3'}
= sort_link(@q, :buyer_name, "Buyer")
%th{class: 'col-xs-3'}
= sort_link(@q, :due_date)
= sort_link(@q, :sort_due_date, "Due date")
%th{class: 'col-xs-3'}
= sort_link(@q, :account_activity_created_at, "Receipt date")
= sort_link(@q, :sort_receipt_date, "Receipt date")
%tbody
- @invoices.each do |x|
%tr

View file

@ -0,0 +1,40 @@
# A custom initializer that enables sorting via custom scopes in Ransack (like the same feature in MetaSearch)
module Ransack
module Adapters
module ActiveRecord
class Context < ::Ransack::Context
# Allows for sorting by custom scopes
#
#
# Define your custom scopes in your model, e. g. sort_by_title_asc and sort_by_title_desc
# (The scopes would sort by some calculated column or a column added via some crazy join, etc.)
#
# In your sort links refer to the scopes like to standard fields, e. g.
# <%= sort_link(@q, :title, 'Crazy calculated title') %>
def evaluate(search, opts = {})
viz = Visitor.new
relation = @object.where(viz.accept(search.base))
if search.sorts.any?
custom_scopes = search.sorts.select do |s|
custom_scope_name = :"sort_by_#{s.name}_#{s.dir}"
relation.respond_to?(custom_scope_name)
end
attribute_scopes = search.sorts - custom_scopes
relation = relation.except(:order)
custom_scopes.each do |s|
custom_scope_name = :"sort_by_#{s.name}_#{s.dir}"
relation = relation.public_send(custom_scope_name)
end
relation = relation.reorder(viz.accept(attribute_scopes)) if attribute_scopes.any?
end
opts[:distinct] ? relation.distinct : relation
end
end
end
end
end