【问题标题】:Rails DRY global variable/functionsRails DRY 全局变量/函数
【发布时间】:2020-07-22 18:08:46
【问题描述】:

在 Rails 应用程序中跨多个控制器使用的代码块保持 DRY 的最佳方法是什么?

例如,我调用了一个 api,当调用它时会根据开始和结束日期变量进行求和/计算。每个控制器都将执行相同的计算,但每个控制器的开始日期和结束日期不同。

最好创建一个全局变量/函数之类的东西来处理这个问题并将其放在我的application_controller 中并通过控制器传递需要的变量吗?

data = HTTParty.get("https://www.url.com/start=#{@contoller.start_date.strftime('%Y%m%d')}&finish=#{@contoller.end_date.strftime('%Y%m%d')}&format=json")
@data = JSON.parse(data.body)
  
rainfall_total = 0
  
@data['data'].each do |data|
 # This adds up rainfall between above date variables
 rainfall = data['value'][0]
 @total_rain = (rainfall_total += rainfall).round(1)
end

所以在上面的代码中我有一个开始和结束日期变量。我有 3 个控制器(stageOne、stageTwo 和 stageThree),其中输入了不同的开始/结束日期,它将计算每个阶段的总降雨量。关于不在所有三个控制器中重复相同代码的最佳做法是什么?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    我会创建一个服务对象来为你处理这个请求。

    你的控制器不应该负责处理这样的业务逻辑,所以你应该推迟到另一个应该有这个责任的对象(模型、服务等)。

    This blog post provides some good examples

    基本上,你会这样处理它:

    创建文件app/services/rainfall_service.rb

    class RainfallService
      def initialize(start_date, end_date)
        @start_date = start_date
        @end_date = end_date
      end
    
      def self.call(*args)
        new(*args).call
      end
    
      def call
        # TODO: implement your code for fetching the data, formatting it, etc
        # return the data you want to use
      end
    end
    

    现在,您可以在控制器中使用您的服务在任何需要的地方获取降雨数据:

    app/controllers/stage_one_controller.rb

    def show
      @rainfall = RainfallService.call(start_date, end_date)
    end
    

    我猜你的开始/结束日期可能来自 params 或其他。

    希望这能给你一个大致的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      相关资源
      最近更新 更多