Skip to content

Commit

Permalink
refactor: removed boilerplate from filterables
Browse files Browse the repository at this point in the history
  • Loading branch information
ryantk committed Sep 19, 2023
1 parent 2af1836 commit 3a40716
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 130 deletions.
58 changes: 58 additions & 0 deletions app/models/concerns/filter_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module FilterForm
extend ActiveSupport::Concern

included do
include ActiveModel::Model
include ActiveModel::Validations
include ActiveModel::Attributes

attribute :sort_by
attribute :sort_order
end

def results
records = scoped_records
filters.each { |filter| records = filter.filter(records) }
records.sorted_by(sort_by:, sort_order:)
end

def number_of_selected(field)
send(field.to_s.singularize).count(&:present?)
end

private

def filters
self.class.filter_attibutes.map do |attr, options|
Support::Concerns::ScopeFilter.new(send(attr), **options)
end
end

class_methods do
def initial_scope(proc)
define_method :scoped_records do
proc.call
end
end

def sort_options(proc)
define_method :available_sort_options do
proc.call
end
end

def filter_by(name, default: -> { [] }, multiple: true, options: -> { [] }, scope: nil)
attribute(name, default:)

filter_attibutes[name] = { scope: scope.presence || "by_#{name}", multiple: }

define_method "available_#{name}_options" do
options.call
end
end

def filter_attibutes
@filter_attibutes ||= {}
end
end
end
75 changes: 10 additions & 65 deletions app/models/frameworks/framework/filtering.rb
Original file line number Diff line number Diff line change
@@ -1,70 +1,15 @@
class Frameworks::Framework::Filtering
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Validations
include FilterForm

attribute :scoped_frameworks, default: -> { Frameworks::Framework }
attribute :status, default: -> { [] }
attribute :provider, default: -> { [] }
attribute :e_and_o_lead, default: -> { [] }
attribute :proc_ops_lead, default: -> { [] }
attribute :category, default: -> { [] }
attribute :provider_contact, default: -> { [] }
attribute :sort_by
attribute :sort_order
get_agents = ->(type_id) { Support::Agent.by_first_name.where(id: Frameworks::Framework.pluck(type_id)) }

def results
frameworks = scoped_frameworks
initial_scope -> { Frameworks::Framework }
sort_options -> { Frameworks::Framework.available_sort_options }

filters.each { |filter| frameworks = filter.filter(frameworks) }

frameworks.sorted_by(sort_by:, sort_order:)
end

def available_category_options
Support::Category.order("title ASC").where(id: Frameworks::FrameworkCategory.pluck(:support_category_id)).pluck(:title, :id)
end

def available_provider_filter_options
Frameworks::Provider.order("short_name ASC").pluck(:short_name, :id)
end

def available_e_and_o_lead_options
Support::Agent.by_first_name.where(id: Frameworks::Framework.pluck(:e_and_o_lead_id))
.map { |agent| [agent.full_name, agent.id] }
end

def available_proc_ops_lead_options
Support::Agent.by_first_name.where(id: Frameworks::Framework.pluck(:proc_ops_lead_id))
.map { |agent| [agent.full_name, agent.id] }
end

def available_status_filter_options
Frameworks::Framework.statuses.map { |label, _id| [label.humanize, label] }
end

def available_provider_contact_options
Frameworks::ProviderContact.sort_by_name("ascending").pluck(:name, :id)
end

def available_sort_options
Frameworks::Framework.available_sort_options
end

def number_of_selected(field)
send(field.to_s.singularize).count(&:present?)
end

private

def filters
[
Support::Concerns::ScopeFilter.new(status, scope: :by_status),
Support::Concerns::ScopeFilter.new(provider, scope: :by_provider),
Support::Concerns::ScopeFilter.new(e_and_o_lead, scope: :by_e_and_o_lead),
Support::Concerns::ScopeFilter.new(proc_ops_lead, scope: :by_proc_ops_lead),
Support::Concerns::ScopeFilter.new(category, scope: :by_category),
Support::Concerns::ScopeFilter.new(provider_contact, scope: :by_provider_contact),
]
end
filter_by :status, options: -> { Frameworks::Framework.statuses.map { |label, _id| [label.humanize, label] } }
filter_by :provider, options: -> { Frameworks::Provider.order("short_name ASC").pluck(:short_name, :id) }
filter_by :e_and_o_lead, options: -> { get_agents[:e_and_o_lead_id].map { |agent| [agent.full_name, agent.id] } }
filter_by :proc_ops_lead, options: -> { get_agents[:proc_ops_lead_id].map { |agent| [agent.full_name, agent.id] } }
filter_by :category, options: -> { Support::Category.order("title ASC").where(id: Frameworks::FrameworkCategory.pluck(:support_category_id)).pluck(:title, :id) }
filter_by :provider_contact, options: -> { Frameworks::ProviderContact.sort_by_name("ascending").pluck(:name, :id) }
end
31 changes: 3 additions & 28 deletions app/models/frameworks/provider/filtering.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,6 @@
class Frameworks::Provider::Filtering
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Validations
include FilterForm

attribute :scoped_providers, default: -> { Frameworks::Provider }
attribute :sort_by
attribute :sort_order

def results
providers = scoped_providers

filters.each { |filter| providers = filter.filter(providers) }

providers.sorted_by(sort_by:, sort_order:)
end

def available_sort_options
Frameworks::Provider.available_sort_options
end

def number_of_selected(field)
send(field.to_s.singularize).count(&:present?)
end

private

def filters
[]
end
initial_scope -> { Frameworks::Provider }
sort_options -> { Frameworks::Provider.available_sort_options }
end
38 changes: 4 additions & 34 deletions app/models/frameworks/provider_contact/filtering.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,8 @@
class Frameworks::ProviderContact::Filtering
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Validations
include FilterForm

attribute :scoped_provider_contacts, default: -> { Frameworks::ProviderContact }
attribute :provider, default: -> { [] }
attribute :sort_by
attribute :sort_order
initial_scope -> { Frameworks::ProviderContact }
sort_options -> { Frameworks::ProviderContact.available_sort_options }

def results
provider_contacts = scoped_provider_contacts

filters.each { |filter| provider_contacts = filter.filter(provider_contacts) }

provider_contacts.sorted_by(sort_by:, sort_order:)
end

def available_sort_options
Frameworks::ProviderContact.available_sort_options
end

def available_provider_filter_options
Frameworks::Provider.order("short_name ASC").pluck(:short_name, :id)
end

def number_of_selected(field)
send(field.to_s.singularize).count(&:present?)
end

private

def filters
[
Support::Concerns::ScopeFilter.new(provider, scope: :by_provider),
]
end
filter_by :provider, options: -> { Frameworks::Provider.order("short_name ASC").pluck(:short_name, :id) }
end
4 changes: 2 additions & 2 deletions app/views/frameworks/frameworks/_index_filters.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<%= expander title: "Status", subtitle: "#{@filtering.number_of_selected(:statuses)} selected", expanded: true do %>
<%= form.govuk_check_boxes_fieldset :status, legend: nil, small: true, form_group: { class: "govuk-!-margin-bottom-0" } do %>
<% @filtering.available_status_filter_options.each do |status| %>
<% @filtering.available_status_options.each do |status| %>
<%= form.govuk_check_box :status, status.last, exclusive: false, label: { text: status.first } %>
<% end %>
<% end %>
Expand All @@ -35,7 +35,7 @@

<%= expander title: "Provider", subtitle: "#{@filtering.number_of_selected(:providers)} selected", expanded: @filtering.number_of_selected(:providers).positive? do %>
<%= form.govuk_check_boxes_fieldset :provider, legend: nil, small: true, form_group: { class: "govuk-!-margin-bottom-0" } do %>
<% @filtering.available_provider_filter_options.each do |option| %>
<% @filtering.available_provider_options.each do |option| %>
<%= form.govuk_check_box :provider, option.last, exclusive: false, label: { text: option.first } %>
<% end %>
<% end %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<%= expander title: "Provider", subtitle: "#{@filtering.number_of_selected(:providers)} selected", expanded: true do %>
<%= form.govuk_check_boxes_fieldset :provider, legend: nil, small: true, form_group: { class: "govuk-!-margin-bottom-0" } do %>
<% @filtering.available_provider_filter_options.each do |option| %>
<% @filtering.available_provider_options.each do |option| %>
<%= form.govuk_check_box :provider, option.last, exclusive: false, label: { text: option.first } %>
<% end %>
<% end %>
Expand Down

0 comments on commit 3a40716

Please sign in to comment.