From db6f78ede42a4513f661f5b6a16881faf7b15b3c Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Mon, 8 Feb 2016 10:36:22 +0200 Subject: [PATCH] Story#112050051 - extend ransack to sort invoices by custom scopes --- app/models/invoice.rb | 12 +++++++++ app/views/admin/invoices/index.haml | 4 +-- config/initializers/eis_ransack.rb | 40 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 config/initializers/eis_ransack.rb diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 5c7dafe85..425202a4c 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -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 diff --git a/app/views/admin/invoices/index.haml b/app/views/admin/invoices/index.haml index f2954f927..4b34dba94 100644 --- a/app/views/admin/invoices/index.haml +++ b/app/views/admin/invoices/index.haml @@ -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 diff --git a/config/initializers/eis_ransack.rb b/config/initializers/eis_ransack.rb new file mode 100644 index 000000000..c23791ef7 --- /dev/null +++ b/config/initializers/eis_ransack.rb @@ -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 \ No newline at end of file