Ruby on rails 在Rails控制器中的方法之间共享变量

Ruby on rails 在Rails控制器中的方法之间共享变量,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个Rails控制器,它有两种方法。这两种方法都使用一些相同的变量,我想知道如何将它们重构为控制器中某个位置的模型中的方法,使它们比现在更可重用 class ChartsController < ApplicationController before_filter :authenticate_user!, :company_id def service_level latest_date = Invoice.where(:account_id => @com

我有一个Rails控制器,它有两种方法。这两种方法都使用一些相同的变量,我想知道如何将它们重构为控制器中某个位置的模型中的方法,使它们比现在更可重用

class ChartsController < ApplicationController

  before_filter :authenticate_user!, :company_id

  def service_level
    latest_date = Invoice.where(:account_id => @company.accounts).maximum(:invc_date)
    invoices_filter = { :invoices => { :invc_date => (latest_date - 3.months)..latest_date } }

    invoices = Invoice.where({:account_id => @company.accounts}.merge(invoices_filter))
    details = InvoiceDetail.joins(:type).where(:invoice_id => invoices)
    freight_details = details.where(:invoice_detail_types => { :category => 'freight' })

    freight_groups = freight_details.group(:family).select("family, count(distinct package_id), sum(base_charge + discount)")


    vol_data = {}
    spend_data = {}

    @charts = {}

     @charts[:service_analysis] = {
      :vol_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.count.to_i] }],
      :spend_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.sum.to_f] }]
    }

    render partial: 'service_level'
  end

  def weight_summary

    latest_date = Invoice.where(:account_id => @company.accounts).maximum(:invc_date)
    invoices_filter = { :invoices => { :invc_date => (latest_date - 3.months)..latest_date } }

    invoices = Invoice.where({:account_id => @company.accounts}.merge(invoices_filter))
    details = InvoiceDetail.joins(:type).where(:invoice_id => invoices)
    freight_details = details.where(:invoice_detail_types => { :category => 'freight' })
    packages = freight_details.joins(:package, :invoice)



    vol_data = {}
    spend_data = {}
    packages.group(:zone).select("zone, count(distinct package_id), sum(base_charge + discount)").each do |row|
      case row.zone
        when '02'..'08', '002'..'008', '102'..'108', '132'..'138', '202'..'208', '242'..'248', '302'..'308'
          zg = row.zone[-1]
        when '09'..'17', '124'..'126', '224'..'226'
          zg = 'AK/HI/PR'
        else
          zg = 'Import/Export'
      end
      vol_data[zg] = (vol_data[zg] || 0) + row.count.to_i
      spend_data[zg] = (spend_data[zg] || 0) + row.sum.to_f
    end
    @charts = {}

    @charts[:weight_analysis] = {
      :vol_data => Hash[(vol_data.sort_by {|key, value| key.scan(/\d+/)[0].to_i})],
      :spend_data => Hash[(spend_data.sort_by {|key, value| key.scan(/\d+/)[0].to_i})]
    }


    render partial: 'weight_summary'
  end
end
class ChartsController@company.accounts)。最大(:invc\u日期)
发票\筛选={:发票=>{:发票\日期=>(最新\日期-3个月)…最新\日期}
发票=发票。其中({:account\u id=>@company.accounts}.merge(发票\u过滤器))
details=InvoiceDetail.join(:type)。其中(:invoice\u id=>invoices)
运费\明细=明细。其中(:发票\明细\类型=>{:类别=>'运费'})
运费\组=运费\组详细信息。组(:系列)。选择(“系列、计数(不同的包裹\ id)、金额(基本费用+折扣)”)
vol_data={}
花费_数据={}
@图表={}
@图表[:服务分析]={
:vol_data=>Hash[freight_groups.map{| row |[InvoiceDetailFamily[row.family].name,row.count.to_i]},
:expense_data=>Hash[freight_groups.map{| row |[InvoiceDetailFamily[row.family].name,row.sum.to_f]]
}
渲染部分:“服务级别”
结束
def重量单位汇总表
最新日期=发票。其中(:account\u id=>@company.accounts)。最大(:invc\u日期)
发票\筛选={:发票=>{:发票\日期=>(最新\日期-3个月)…最新\日期}
发票=发票。其中({:account\u id=>@company.accounts}.merge(发票\u过滤器))
details=InvoiceDetail.join(:type)。其中(:invoice\u id=>invoices)
运费\明细=明细。其中(:发票\明细\类型=>{:类别=>'运费'})
包裹=运费\详细信息。连接(:包裹,:发票)
vol_data={}
花费_数据={}
包裹。分组(:区域)。选择(“区域、计数(不同的包裹id)、总和(基本费用+折扣)”。每行|
案例行。区域
当‘02’、‘08’、‘002’、‘008’、‘102’、‘108’、‘132’、‘138’、‘202’、‘208’、‘242’、‘248’、‘302’、‘308’
zg=行分区[-1]
当'09'、'17'、'124'、'126'、'224'、'226'
zg='AK/HI/PR'
其他的
zg=‘导入/导出’
结束
vol_data[zg]=(vol_data[zg]| 0)+row.count.to_i
支出数据[zg]=(支出数据[zg]| | 0)+row.sum.to_f
结束
@图表={}
@图表[:权重分析]={
:vol_data=>Hash[(vol_data.sort_by{| key,value | key.scan(/\d+/)[0]。to_i}],
:spend_data=>Hash[(spend_data.sort_by{| key,value | key.scan(/\d+/)[0]。to_i}]
}
渲染部分:“权重\u摘要”
结束
结束

我建议使用模型类方法来处理数据。比如说

freight_details = details.where(:invoice_detail_types => { :category => 'freight' })

freight_groups = freight_details.group(:family).select("family, count(distinct package_id), sum(base_charge + discount)")


vol_data = {}
spend_data = {}

@charts = {}

 @charts[:service_analysis] = {
  :vol_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.count.to_i] }],
  :spend_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.sum.to_f] }]
}
可以移动到返回
图表的模型类方法。同样,您可以重构第二个方法。任何类型的业务逻辑和数据处理都应该在模型中处理


此外,我可以看到控制器中有太多未使用的局部变量。控制器应尽可能薄

我建议使用模型类方法来处理数据。比如说

freight_details = details.where(:invoice_detail_types => { :category => 'freight' })

freight_groups = freight_details.group(:family).select("family, count(distinct package_id), sum(base_charge + discount)")


vol_data = {}
spend_data = {}

@charts = {}

 @charts[:service_analysis] = {
  :vol_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.count.to_i] }],
  :spend_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.sum.to_f] }]
}
可以移动到返回
图表的模型类方法。同样,您可以重构第二个方法。任何类型的业务逻辑和数据处理都应该在模型中处理


此外,我可以看到控制器中有太多未使用的局部变量。控制器应尽可能薄

使用像decorator这样的概念

module Chart
   extend self
   def service_analysis(freight_groups, freight_groups)

   end
end
class ChartsController < ApplicationController
    @chart = Chart.service_analysis(freight_groups, freight_groups)
end
模块图
延伸自我
def服务分析(运费组、运费组)
结束
结束
类ChartsController<应用程序控制器
@图表=图表。服务分析(运费组、运费组)
结束

注意:不要将计算代码放在视图中,它很慢

请使用decorator之类的概念

module Chart
   extend self
   def service_analysis(freight_groups, freight_groups)

   end
end
class ChartsController < ApplicationController
    @chart = Chart.service_analysis(freight_groups, freight_groups)
end
模块图
延伸自我
def服务分析(运费组、运费组)
结束
结束
类ChartsController<应用程序控制器
@图表=图表。服务分析(运费组、运费组)
结束

注意:不要将计算代码放在视图中,它很慢

如果您决定将其保留在控制器中,请尝试以下操作:

class ChartsController < ApplicationController before_filter :authenticate_user!, :company_id before_filter :load_data, :only => [:service_level, weight_summary] def service_level freight_groups = @freight_details.group(:family).select("family, count(distinct package_id), sum(base_charge + discount)") @charts = {} @charts[:service_analysis] = { :vol_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.count.to_i] }], :spend_data => Hash[freight_groups.map { |row| [InvoiceDetailFamily[row.family].name, row.sum.to_f] }] } render partial: 'service_level' end def weight_summary packages = @freight_details.joins(:package, :invoice) vol_data = {} spend_data = {} packages.group(:zone).select("zone, count(distinct package_id), sum(base_charge + discount)").each do |row| case row.zone when '02'..'08', '002'..'008', '102'..'108', '132'..'138', '202'..'208', '242'..'248', '302'..'308' zg = row.zone[-1] when '09'..'17', '124'..'126', '224'..'226' zg = 'AK/HI/PR' else zg = 'Import/Export' end vol_data[zg] = (vol_data[zg] || 0) + row.count.to_i spend_data[zg] = (spend_data[zg] || 0) + row.sum.to_f end @charts = {} @charts[:weight_analysis] = { :vol_data => Hash[(vol_data.sort_by {|key, value| key.scan(/\d+/)[0].to_i})], :spend_data => Hash[(spend_data.sort_by {|key, value| key.scan(/\d+/)[0].to_i})] } render partial: 'weight_summary' end private def load_data latest_date = Invoice.where(:account_id => @company.accounts).maximum(:invc_date) invoices_filter = { :invoices => { :invc_date => (latest_date - 3.months)..latest_date } } invoices = Invoice.where({:account_id => @company.accounts}.merge(invoices_filter)) details = InvoiceDetail.joins(:type).where(:invoice_id => invoices) @freight_details = details.where(:invoice_detail_types => { :category => 'freight' }) end end 类ChartsController<应用程序控制器 在\u筛选器之前:验证\u用户!,:公司id 在\u筛选器之前:加载\u数据,:only=>[:服务\u级别,权重\u摘要] def服务级别 运费组=@freight\u details.group(:family)。选择(“family,count(不同的包装标识),sum(基本费用+折扣)”) @图表={} @图表[:服务分析]={ :vol_data=>Hash[freight_groups.map{| row |[InvoiceDetailFamily[row.family].name,row.count.to_i]}, :expense_data=>Hash[freight_groups.map{| row |[InvoiceDetailFamily[row.family].name,row.sum.to_f]] } 渲染部分:“服务级别” 结束 def重量单位汇总表 包裹=@freight\u details.join(:包裹,:发票) vol_data={} 花费_数据={} 包裹。分组(:区域)。选择(“区域、计数(不同的包裹id)、总和(基本费用+折扣)”。每行| 案例行。区域 当‘02’、‘08’、‘002’、‘008’、‘102’、‘108’、‘132’、‘138’、‘202’、‘208’、‘242’、‘248’、‘302’、‘308’ zg=行分区[-1] 当'09'、'17'、'124'、'126'、'224'、'226' zg='AK/HI/PR' 其他的 zg=‘导入/导出’ 结束 vol_data[zg]=(vol_data[zg]| 0)+row.count.to_i 支出数据[zg]=(支出数据[zg]| | 0)+row.sum.to_f 结束 @图表={} @图表[:权重分析]={ :vol_data=>Hash[(vol_data.sort_by{| key,value | key.scan(/\d+/)[0]。to_i}], :spend_data=>Hash[(spend_data.sort_by{| key,value | key.scan(/\d+/)[0]。to_i}] } 渲染部分:“权重\u摘要” 结束 私有的 def加载数据 最新日期=发票。其中(:account\u id=>@company.accounts)。最大(:invc\u日期) 发票\过滤器={:发票=>{:发票\日期=>(l)