【问题标题】:Update multiple records from a table in a single form in rails?在rails中以单一形式更新表中的多个记录?
【发布时间】:2020-08-21 15:01:52
【问题描述】:

我有一个包含 72 个时间段的页面,每个时间段旁边都有一个单选按钮,用于表示可用/不可用。

我希望医生能够选择他们是否可用,然后在完成后单击“更新”。

这意味着表单必须接受所有 72 条记录。

我(认为)我可以通过一些非常低级的编程来解决这个问题。但我不知道'rails way'是什么?

到目前为止我所知道的

  • 建议here不要使用form_for,而是使用form_tag

我尝试过的

如果它不好(可能是这样),请不要使用这个想法。但我的想法是首先在接下来的 3 天内生成所有可能的时间

time_now = Time.now 
current_time =  time_now 
three_days = time_now + 3.days

hours = []
(current_time.beginning_of_hour.to_datetime.to_i .. three_days.beginning_of_hour.to_datetime.to_i).step(1.hour) do |date|
hours << Time.at(date)
end

    @hours = hours

然后,使用这些开始时间作为散列中的键,假设 available: false 作为散列中的值(除非 Availability.where(user: current_user).all 另有说明),并将其传递给视图以设置单选按钮的默认位置,然后医生可以随意更新单选按钮并在完成后提交。

问题是

i) 我不知道这是一个好/坏/丑陋的方法 ii)(主要问题)我将如何为散列中的每个键/值对创建一个带有单选按钮的表单? (一个提交按钮)

注意:到目前为止,我在 rails 中知道的唯一表单是通过 form_for,但我热衷于使用此类表单的最佳实践

【问题讨论】:

    标签: ruby-on-rails form-for


    【解决方案1】:

    对此没有“轨道方式”。 Rails 在很多方面都是固执己见的。但是,不是这样的。

    在我看来,您的问题至少有两个部分。首先是构建合适的数据结构。我认为您可以通过以下方式清理现有代码:

    time_now = Time.now
    start_time = time_now.beginning_of_hour.to_datetime.to_i
    end_time = (time_now + 3.hours).beginning_of_hour.to_datetime.to_i
    
    @hours = (start_time..end_time).step(1.hour).map {|t| Time.at(t)}
    

    ...这主要是化妆品。 (请注意,我使用 3.hours 而不是 3.days 只是为了保持输出更短。)它为您节省了一些作业并使用 .map 而不是整个推送到 array 位正在做。

    我推测您需要arrayhashes,而不是times 的数组。也许是这样的:

    time_now = Time.now
    start_time = time_now.beginning_of_hour.to_datetime.to_i
    end_time = (time_now + 3.hours).beginning_of_hour.to_datetime.to_i
    
    @hours = (start_time..end_time).step(1.hour).map {|t| {time_slot: Time.at(t)}}
    

    ...您可能希望包括 time_slot 当前是否可用:

    time_now = Time.now
    start_time = time_now.beginning_of_hour.to_datetime.to_i
    end_time = (time_now + 3.hours).beginning_of_hour.to_datetime.to_i
    
    @hours = (start_time..end_time).step(1.hour).map do |t| 
      time_slot = Time.at(t)
      {time_slot: time_slot, time_slot_available?: time_slot_available?(time_slot)}
    end
    

    ...这需要time_slot_available? 方法。出于测试目的,我将其存根为:

    def time_slot_available?(time_slot)
      [true, false].sample
    end
    

    ...最终会给你类似的东西:

    [
      {:time_slot=>2020-08-21 08:00:00 -0700, :time_slot_available?=>false}, 
      {:time_slot=>2020-08-21 09:00:00 -0700, :time_slot_available?=>true}, 
      {:time_slot=>2020-08-21 10:00:00 -0700, :time_slot_available?=>false}, 
      {:time_slot=>2020-08-21 11:00:00 -0700, :time_slot_available?=>false}
    ]
    

    当然,time_slot_available? 会检查数据库。这种特殊的方法很糟糕,因为它可能会产生 N+1,但这只是为了说明目的。

    现在,您可以按照您的描述创建一个单一的、庞大的表单。或者,您可以为每个 time_slot 生成一个没有表单的单选按钮,然后附加一些 javascript,在每次单击按钮时进行 ajax 调用 - 将time_slot 设置为可用或不可用,视情况而定。

    从用户体验的角度来看,我喜欢后者(当用户点击按钮时,工作会被保存),但这是对偏好、风格、编程技能以及可能其他因素的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多