【问题标题】:Using multiple input fields for one attribute为一个属性使用多个输入字段
【发布时间】:2012-06-24 00:49:21
【问题描述】:

我是 Rails 新手,如果这个太简单了,请见谅。

我的模型中有一个 datetime 属性,我尝试将值与 3 个表单元素一起放入其中。 第一个用于日期并且是输入表单(我使用 bootstrap-datepicker-rails 并且我想坚持使用它)。在第二个中,我希望有一个小时选择框,第三个是分钟选择框。

所以我看到我可以使用 DateHelpers datetime_select 但是我不能再使用 bootstrap-datepicker 了。 那么通过使用多个表单输入元素来填充属性(日期时间)的正确方法是什么。我看到有类似assign_multiparameter_attributes的东西,但文档并没有太大帮助:-(

谢谢

【问题讨论】:

    标签: ruby-on-rails datetime datepicker


    【解决方案1】:

    对我来说,这似乎是控制器要解决的问题。该模型仍然有效,如果它以“Rails”方式接收其属性,它将正常工作。我的解决方案涉及控制器修改params 哈希,以便模型甚至不知道视图中的更改。这取决于 behavior in ActiveRecord 可以被视为私有 API,所以……公平警告 :-)

    假设你有这个模型:

    # app/models/example.rb
    class Example < ActiveRecord::Base
      attr_accessible :started_at    # this is a DateTime
    end
    

    调整您的视图以使用普通的 text_field_tag 作为日期部分(将通过 bootstrap-datepicker 增强)和 Rails 的 time_select 作为时间部分:

    # app/views/examples/_form.html.erb
    <%= form_for(@example) do |f| %>
      <p>
        <%= f.label :started_at %>
        <%= text_field_tag :started_at, @example.started_at.try(:to_date) %>
        <%= f.time_select :started_at, :ignore_date => true %>
      </p>
    
      <p><%= f.submit %></p>
    <% end %>
    

    请注意,我们正在使用try,因为此表单将为新的持久记录呈现。这避免了started_at 属性为nil 时的问题。

    然后在控制器中创建一个before_filter 以在params 散列被发送到模型之前对其进行修改:

    class ExamplesController < ApplicationController
      before_filter :fix_params, :only => [:create, :update]
    
      # ...
    
    private
    
      def fix_params
        date = Date.parse(params.delete(:started_at))
    
        params[:example].merge!({
          'started_at(1i)' => date.year.to_s,
          'started_at(2i)' => date.month.to_s,
          'started_at(3i)' => date.day.to_s
        })
      end
    end
    

    本质上,我们将params[:started_at] 解析为日期并将其分配给params[:example] 的正确键。那么当参数最终传递给模型时,ActiveRecord 会正确分配模型的started_at 属性。

    您需要进行一些错误检查和验证,但这应该适合您。

    【讨论】:

    • "fix_params"的第一行应该有params[:example],否则为nil。
    • 实际上并非如此。由于我使用的是text_field_tag 而不是f.text_field,因此文本字段的名称是started_at,而不是example[started_at]。所以它确实存在于 params 哈希的顶层。
    • 哦,好吧,我跳过了。我已经用 f.text_field 以这种方式实现了它,而且效果很好。
    猜你喜欢
    • 2014-10-20
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多