【问题标题】:How not to repeat this code in my models如何不在我的模型中重复此代码
【发布时间】:2009-07-23 13:36:45
【问题描述】:

我在一个模型中有这段代码,它根据运行该方法的时间设置开始日期和结束日期。

让我们直接进入代码示例:

#MODEL
now = Time.now
if now.hour >= 17 && now.hour <= 23
    #night
    n = now+1.day
    startd = Time.local(now.year, now.month, now.day, 17, 00, 00)
    endd = Time.local(n.year, n.month, n.day, 8, 00, 00)
elsif now.hour >= 0 && now.hour <= 7
    #morning
    n = now-1.day
    startd = Time.local(n.year, n.month, n.day, 8, 00, 00)
    endd = Time.local(now.year, now.month, now.day, 17, 00, 00)     
end

然后在一个模型(相同或另一个)中,我试图在一个 find 中运行这个函数。

#MODEL(SAME OR OTHER)
Model.find(:all, 
 :conditions => ['created_at >= ? AND created_at <= ?', startd, endd])

问题是我要使用那个函数来设置开始和结束日期很多,我不知道放在哪里不重复自己。它将用于不同的模型。

感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails model


    【解决方案1】:

    您可以将它包含在lib 目录中的模块中。 RAILS_ROOT/lib 中的所有 ruby​​ 文件都会自动加载。

    # time_calculations.rb
    
    module TimeCalculations
      def calc_start_and_end_times
        now = Time.now
        if now.hour >= 17 && now.hour <= 23
            #night
            n = now+1.day
            startd = Time.local(now.year, now.month, now.day, 17, 00, 00)
            endd = Time.local(n.year, n.month, n.day, 8, 00, 00)
        elsif now.hour >= 0 && now.hour <= 7
            #morning
            n = now-1.day
            startd = Time.local(n.year, n.month, n.day, 8, 00, 00)
            endd = Time.local(now.year, now.month, now.day, 17, 00, 00)     
        end
        [startd, endd]
      end
    end
    
    # model.rb
    
    class Model < ActiveRecord::Base
      extend TimeCalculations
    
      def self.my_find()
        startd, endd = calc_start_and_end_times
        Model.find(:all, 
          :conditions => ['created_at >= ? AND created_at <= ?', startd, endd])
      end
    
    end
    

    已编辑以反映最终/正确答案。

    【讨论】:

    • 这听起来像是一个很好的解决方案,我已经尝试过了,但它给了我“#<0xb6f3bb30>
    【解决方案2】:

    最简单的方法是将代码添加到模块中,可能是在初始化程序中:

    module SmartDates
    
      def start_date
        now = Time.now
        if now.hour >= 17 && now.hour <= 23
          #night
          n = now+1.day
          return Time.local(now.year, now.month, now.day, 17, 00, 00)
        elsif now.hour >= 0 && now.hour <= 7
          #morning
          n = now-1.day
          return Time.local(n.year, n.month, n.day, 8, 00, 00)
        end
      end
    
      def end_date
        now = Time.now
        if now.hour >= 17 && now.hour <= 23
          #night
          n = now+1.day
          return Time.local(n.year, n.month, n.day, 8, 00, 00)
        elsif now.hour >= 0 && now.hour <= 7
          #morning
          n = now-1.day
          return Time.local(now.year, now.month, now.day, 17, 00, 00)
        end
      end
    
    end
    
    # Now include your module
    ActiveRecord::Base.include(SmartDates)
    ActionController::Base.include(SmartDates)
    

    现在start_dateend_date 可用于模型和控制器。

    【讨论】:

    • 谢谢,模块代码进入/lib?包含代码呢,你会把它放在哪里?
    • 我可能会把它放在一个初始化器中,正如我上面提到的。在config/initializers/smart_dates.rb 什么的。也许我会将模块放在 lib/ 中,并将包含在初始化程序中。
    【解决方案3】:

    您可以在模型类中添加方法 find_by_date_range (startd, endd) 并使用 Model.find_by_date_range(something, something_else)

    【讨论】:

    • 那么,计算开始和结束日期时间的部分在哪里?
    • 让我解释一下。首先,您需要决定 - 将在代码中的其他地方使用开始/结束计算。如果是 - 移动负责计算开始和结束的方法将很有用。下一步 - 在您的模型中开发查找方法,它将按照您的标准返回所有记录(erik 已经输入了很好的示例)。还有另一个有用的解决方案 - 您可以使用 named_scope - apidock.com/rails/ActiveRecord/NamedScope/ClassMethods/…
    • 更正我的评论 - “如果是 - 移动方法会很有用,负责计算模块的开始和结束,如果不是 - 没那么必要”
    猜你喜欢
    • 2018-03-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多