Ruby on rails 从Rails日期模型对象帮助器手动提取日期

Ruby on rails 从Rails日期模型对象帮助器手动提取日期,ruby-on-rails,Ruby On Rails,我正在使用Rails(v5.1)表单,该表单使用以下参数提交通过三个下拉列表(d/m/y)选择的日期 {..."next_inspection_date(3i)"=>"14", "next_inspection_date(2i)"=>"8", "next_inspection_date(1i)"=>"2019"...} 借助Rails的魔力,MyModel.new(params)知道如何处理这个问题,但我想在提交表单时应用一些额外的逻辑。我可以写这样的东西 TimeWithZ

我正在使用Rails(v5.1)表单,该表单使用以下参数提交通过三个下拉列表(d/m/y)选择的日期

{..."next_inspection_date(3i)"=>"14", "next_inspection_date(2i)"=>"8", "next_inspection_date(1i)"=>"2019"...}
借助Rails的魔力,
MyModel.new(params)
知道如何处理这个问题,但我想在提交表单时应用一些额外的逻辑。我可以写这样的东西

TimeWithZone.parse("#{params[:next_inspection_date(1i)]}-#{params[:next_inspection_date(2i)]}-#{params[:next_inspection_date(3i)]}")
提取一个日期,但这会很快重复几个日期。手动干燥可能会产生一些非常简洁的内容来阅读,并引入大量的逻辑,这将真正分散我的注意力。我想知道Rails是否有一个内置的助手,这样我就可以编写

MyModel.next_inspection_date = useful_date_helper(params, :next_inspection_date)
Rails指南仅说明
更新
新建
等方法了解如何处理这些参数


提前感谢您的建议。

这些属性被称为多参数属性,不幸的是,这些功能被深深地埋藏在其中。但您可以只使用ActiveRecord的实现而不保存记录:

next_inspection_date = MyModel.new(params.permit(:next_inspection_date)).next_inspection_date
如果您正在构建查询对象或虚拟模型之类的东西,您还可以复制它,这确实更有趣:

module MultiparamExtractor
  # Extracts 'i' from foo(3i)
  REGEXP = /\w*\(\d*(?<type>[a-z])\)/.freeze

  # Extracts an array of cast values from a hash containing one multi-parameter attribute
  # @param hash [Hash|ActionController::Parameters]
  # @return [Array]
  def self.call(multi_params)
    # coerce input into a hash
    if multi_params.respond_to?(:permit)
      multi_params.dup.permit!.to_h  # .dup prevents mutating the arguments
    else
      multi_params
    end.sort # sorts by key <=> other key and returns an array
       .map do |(key,value)|
         typecast(value, REGEXP.match(key)[:type])
       end
  end

  private
  # @todo handle casting more types
  def self.typecast(value, type)
    case type
    when 'i'
      value.to_i
    else
      value
    end
  end
end

您是否打算在将其保存到模型中之前进行更改?如果是,为什么不在控制器的创建/更新操作中(保存之前):
params[:next\u inspection\u date]=您的\u date
。如果您不清楚我的意思,只需共享操作代码,我将添加您需要进行更改的答案。TL;DR:我想在内存中更新@MyModelInstance并在不保存的情况下渲染视图。更长的版本:我在表单中添加了一个按钮,用于查询外部服务,该服务可以为用户填充此表单的某些部分。用户点击“查找”,表单被提交;我在服务器端执行API查询,并重新呈现表单,以反映API结果以及用户在单击“查找”之前所做的任何更改。您可以做的是提取参数值,如
next=params[:next_inspection_date]
并将其与API请求的响应一起单独发送回?因此,由于rails表单帮助程序,
params[:next\u inspection\u date]
没有定义-定义的是
params[:next\u inspection\u date(1i)
params[:next\u inspection\u date(2i)
,等等。提取它是个问题。
# Just for the sake of the example
params = ActionController::Parameters.new("next_inspection_date(3i)"=>"14", "next_inspection_date(2i)"=>"8", "next_inspection_date(1i)"=>"2019", "foo" => "bar")
date = Date.new(*MultiparamExtractor.call(params.permit(:next_inspection_date))).in_time_zone
# Wed, 14 Aug 2019 00:00:00 UTC +00:00