【问题标题】:Rails, using time_select on a non active record modelRails,在非活动记录模型上使用 time_select
【发布时间】:2010-11-01 23:51:37
【问题描述】:

我正在尝试使用 time_select 将时间输入到模型中,然后执行一些计算。

time_select 帮助器准备返回的参数,以便可以在对 Active Record 对象的多参数分配中使用它。

类似下面的东西

  Parameters: {"commit"=>"Calculate", "authenticity_token"=>"eQ/wixLHfrboPd/Ol5IkhQ4lENpt9vc4j0PcIw0Iy/M=", "calculator"=>{"time(2i)"=>"6", "time(3i)"=>"10", "time(4i)"=>"17", "time(5i)"=>"15", "time(1i)"=>"2009"}}

我的问题是,在非活动记录模型中使用这种格式的最佳方式是什么。也在旁注中。 (5i)、(4i) 等是什么意思? (除了区分不同时间值的明显原因,基本上就是这样命名的原因)

谢谢

【问题讨论】:

    标签: ruby-on-rails activerecord time variadic-functions


    【解决方案1】:

    您可以在非活动记录模型中创建方法如下

    # This will return a Time object from provided hash
    def parse_calculator_time(hash)
      Time.parse("#{hash['time1i']}-#{hash['time2i']}-#{hash['time3i']} #{hash['time4i']}:#{hash['time5i']}")
    end
    

    然后您可以从控制器操作中调用该方法,如下所示

    time_object = YourModel.parse_calculator_time(params[:calculator])
    

    它可能不是最好的解决方案,但使用起来很简单。

    干杯:)

    【讨论】:

    • 非常感谢您的宝贵回答。
    【解决方案2】:

    数字后面的字母代表您希望将其转换为的类型。在这种情况下,integer。也可以是 f 代表 floats 代表 string

    我自己就是这样做的,我能找到的最简单的方法是将 Rails 代码复制/粘贴到我的基本模块(或抽象对象)中。

    我从ActiveRecord::Base逐字复制了以下函数

    • assign_multiparameter_attributes(pairs)
    • extract_callstack_for_multiparameter_attributes(pairs)
    • type_cast_attribute_value(multiparameter_name, value)
    • find_parameter_position(multiparameter_name)

    我还有以下调用/使用它们的方法:

    def setup_parameters(params = {})
      new_params = {}
      multi_parameter_attributes = []
    
      params.each do |k,v|
        if k.to_s.include?("(")
          multi_parameter_attributes << [ k.to_s, v ]
        else
          new_params[k.to_s] = v
        end
      end
    
      new_params.merge(assign_multiparameter_attributes(multi_parameter_attributes))
    end
    
    # Very simplified version of the ActiveRecord::Base method that handles only dates/times
    def execute_callstack_for_multiparameter_attributes(callstack)
      attributes = {}
    
      callstack.each do |name, values|
    
        if values.empty?
          send(name + '=', nil)
        else
          value = case values.size
            when 2 then t = Time.new; Time.local(t.year, t.month, t.day, values[0], values[min], 0, 0)
            when 5 then t = Time.time_with_datetime_fallback(:local, *values)
            when 3 then Date.new(*values)
            else nil
          end
    
          attributes[name.to_s] = value
        end
    
      end
    
      attributes
    end
    

    如果您找到更好的解决方案,请告诉我:-)

    【讨论】:

    • 此解决方案适用于 Rails 3 还是 4?当我尝试它时,它似乎在 Rails 4 中不起作用。
    • @MattHuggins 老实说这可能适用于 Rails 2,所以它非常很可能在 Rails 4 中不起作用。
    • 看起来这仍然是 Rails 4.0.1 的问题。有一个未解决的问题:github.com/rails/rails/pull/8189
    猜你喜欢
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多