【问题标题】:Rails - create or update according to time rangeRails - 根据时间范围创建或更新
【发布时间】:2014-06-25 17:21:08
【问题描述】:

我有一个表,如果其中一列在日期范围内(今天),我需要创建一个新条目或更新。

例如,我有一个带有 [name, time] 的班车登记表,其中姓名代表某人,时间是他想乘坐班车的时间。 每个(姓名)每天最多可以注册一次。

当有人注册时,我想更新(同一天的)现有行(如果存在),或者创建一个新行。

以下查询提取相关行(如果存在):

Shuttle.where('name= ? AND time BETWEEN ? AND ?', params[:name], DateTime.now.beginning_of_day, DateTime.now.end_of_day)

尝试使用 first_or_create 和等效项,但找不到正确的语法来应用范围查询。

有什么想法吗?

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4


    【解决方案1】:

    first_or_create 不适用于这种情况,因为条件作为更新的值没有意义。这就像说“找到时间在这一天的任何时间的班车,如果找不到,则创建一个时间在这一天的任何时间的班车”。这没有任何意义:您需要一个特定的时间来创建航天飞机。

    你需要考虑你想要做什么的逻辑:至少对我来说并不明显。

    【讨论】:

    • 你基本上是对的。但是,班车是[姓名,时间],每个“姓名”每天可以注册一次。如果有人在某一天已经注册,我想将小时更新为新值。
    • 您应该将此信息添加到您的问题中,并举例说明。
    • first_or_initialize 不起作用——您需要在 where 子句中使用参数散列来设置 first_or_initialize 的属性。 IE,Shuttle.where(:name => params[:name]).first_or_initialize 可以,但是 Shuttle.where("name = :name", :name => params[:name]") 不会
    【解决方案2】:

    试试这个:

     Shuttle.where(:name => params[:name]).
             where(:time => DateTime.now.beginning_of_day..DateTime.now.end_of_day)).
             first_or_create(:time => DateTime.now)
    

    参考:http://guides.rubyonrails.org/v3.2.13/active_record_querying.html#first_or_create

    【讨论】:

      【解决方案3】:

      如果我理解你,我会做以下事情

      @shuttle = Shuttle.where('name= ? AND time BETWEEN ? AND ?', params[:name], DateTime.now.beginning_of_day, DateTime.now.end_of_day).first
      @shuttle.columnname = "new value"
      @shuttle.save
      

      如果你正在做多个

      @shuttles = Shuttle.where('name= ? AND time BETWEEN ? AND ?', params[:name], DateTime.now.beginning_of_day, DateTime.now.end_of_day)
      @shuttles.each do |shuttle|
        shuttle.columnname = "new value"
        shuttle.save
      end
      

      【讨论】:

      • 更新没问题,但他正在尝试做一个first_or_create。 (这没有意义,但这就是他的要求)。如果@shuttle = nil,您的代码也会在第 2 行引发异常。
      • 没错,如果不存在我需要创建。
      【解决方案4】:

      这样的事情呢?

      @shuttle = Shuttle.where(
            name: params[:name],
            time: DateTime.now.beginning_of_day..DateTime.now.end_of_day
          ).first_or_initialize do |s|
        s.attribute = value
        s.save
      end
      

      【讨论】:

      • 看起来不错,我需要尝试一下,看看它是否有效。在这种情况下,什么是“价值”?
      • 价值是你想要的。由于您想在找不到对象时创建它,因此您应该知道要赋予它的值。这只是一个如何在对象上设置属性值的示例,无论它是新的还是持久的:s.foo = "whatever"
      • 我对 find_or_initialize_by 的问题是我无法获得正确的语法来应用时间范围查询。
      猜你喜欢
      • 2019-11-06
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多