我正在为网站进行一些报告/分析。目标是过滤到我从数据库查询并运行分析的一组@loans。希望使用数据库来获取已过滤的@loans,针对这些记录运行指标,然后返回要在页面上显示的指标。
这种关系并不是很复杂,但我所做的就是:
模型关系
# loan.rb
belongs_to :loan_category
belongs_to :loan_type
belongs_to :partner
# loan_category.rb
has_many :loans
# loan_type.rb
has_many :loans
# partner.rb
has_many :loans
belongs_to :company
# company.rb
has_many :partners
过滤表格
我将报告视为资源,因为用户可以将过滤器保存为saved_report。
用户按2个给定标准过滤:
parter ID#3
或loan_type ID#6
过滤,但绝不会超过一个) )起初看起来相当微不足道,直到我开始尝试实现这一点。问题在于必须考虑各种情况:
我正试图以一种非常丑陋的方式来实现这一目标。这些例子将证明我的意思:
/reports
=>概述报告,默认为当月。/reports?from=2014-01-01
=>概述报告,从给定日期到当天/reports/3
=>一个saved_report,可以按四个(partner,company,loan_category,loan_type)和日期范围中的任何一个进行过滤/reports/partner?partner_id=3
=>以骇人的方式使用params[:id]
,我的控制器代码知道我想要由给定的合作伙伴过滤/reports/loan_type?loan_type_id=7&from=2014-01-01&to=2014-01-31
=>再次使用params[:id]
我知道按指定日期范围的给定loan_type进行过滤这会导致一些非常丑陋的控制器代码:
报告控制器
# always overview report; just filter by specified date range
def index
# Dummy code to show what I'm doing...
@loans = Loan.where(created_at >= params[:from]).where(created_at <= params[:to])
# ...use @loans to calculate metrics for report...
end
def show
is_saved_report = false
@saved_report = nil
# feels very "hackish" to do this...
case params[:id]
when "partner"
@loans = Loan.where(partner_id: params[:partner_id])
when "company"
@loans = Loan.includes(:partner).where(partner.company_id: params[:company_id])
when "loan_category"
@loans = Loan.where(loan_category_id: params[:loan_category_id])
when "loan_type"
@loans = Loan.where(loan_type_id: params[:loan_type_id])
else
# if none of the 4 "keywords" was used, assume it's a saved_report ID
is_saved_report = true
@saved_report = SavedReport.find(params[:id])
# grab filters from @saved_report and use them to run ANOTHER case statement...
end
# add date range filters
if is_saved_report == true
@loans.where(created_at >= @saved_report.from).where(created_at <= @saved_report.to)
else
@loans.where(created_at >= params[:from]).where(created_at <= params[:to])
end
# at this point, should have filtered list of @loans to run metrics on
@total_loans = @loans.size
# ...have to have more conditionals to display metrics for specific type of report...
end
正如您所看到的,代码非常快速地变得非常简单。必须有更好的方法来解决这个问题。我简直想不出一个更清洁的解决方案。我一直在研究这个问题,现在我没有想清楚。
我对这种情况有任何建议或想法。一开始似乎微不足道的东西变得有点噩梦。