【问题标题】:Rails form scope and persisted valueRails 形成范围和持久值
【发布时间】:2014-07-15 15:08:52
【问题描述】:

我有一个 Rails 3.2.18 应用程序有问题。

基本上每条记录都是一个Call,每个Call都有很多单元。单位是具有诸如(服务中、停止服务等)状态的车辆。

创建呼叫时,我希望仅列出标记为服务中的单元以进行调度。所以我在 Unit 模型上创建了一个范围:

单位.rb

scope :in_service, lambda { where(status_id: Status.find_by_unit_status("In Service").id)}

在我的呼叫助手中,我有一个方法可以选择单元并附加它们的单元类型以及它们是否在另一个呼叫中处于活动状态,这样调度员就不会想重复调度一个单元。

calls_helper.rb

def unit_select
    Unit.active.order("unit_name").map{|unit| unit.calls.where(call_status: "open").empty? ? ["#{unit.unit_name} #{unit.unit_type.unit_type}", unit.id] : ["#{unit.unit_name} (on call) #{unit.unit_type.unit_type}", unit.id] }
end

这就是问题所在。如果我将辅助方法更改为以下内容:

def unit_select
    Unit.active.in_service.order("unit_name").map{|unit| unit.calls.where(call_status: "open").empty? ? ["#{unit.unit_name} #{unit.unit_type.unit_type}", unit.id] : ["#{unit.unit_name} (on call) #{unit.unit_type.unit_type}", unit.id] }
end

将 in_service 范围方法附加到 unit_select 帮助器,它确实只选择了正在服务的单元。这很好,但是当您去编辑呼叫时,如果该单元在呼叫创建后已更改其状态,则该单元将从表单中的记录中删除

_form.html.erb

<%= f.select(:unit_ids, unit_select,  {}, {:multiple => true, :class => 'select'}) %>

我明白为什么会发生这种情况,因为表单是根据状态为“服务中”的单元进行选择的,但我需要弄清楚如何让单元分配在表单中持续存在。

所以在朋友的帮助下,我们想出了这个辅助方法:

def unit_select
(@call.units.to_a + Unit.active.in_service.order("unit_name")).map{|unit| unit.calls.where(call_status: "open").empty? ? ["#{unit.unit_name} #{unit.unit_type.unit_type}", unit.id] : ["#{unit.unit_name} (on call) #{unit.unit_type.unit_type}", unit.id] }
end

现在这可以正常工作了,无论单元的状态如何,当您编辑时,单元都会保留在表单中。这就是事情变得奇怪的地方。

假设您编辑了记录,并且想要取消该单元并分配一个不同的单元。它不允许你这样做。无论我做什么,它都会继续保持@call.unit_ids 的值。

以下是关联的样子: 调用.rb

has_many :call_units
has_many :units, through: :call_units

单位.rb

has_many :call_units
has_many :calls, through: :call_units

除此之外,我在创建回拨电话时发现了另一个问题。 (基本上采用原始呼叫数据并根据初始呼叫创建回程。创建回程时,它将在数组中两次将相同的 unit_id 分配给呼叫。因此看起来呼叫中有两个单元,但它们确实是同一个单元列出了两次。这是我的返回操作在控制器中的样子。

calls_controller.rb

def new_return
    original_call = Call.find(params[:id])
    @call = Call.new(
      caller_name: original_call.caller_name,
      special_equipment_ids: original_call.special_equipment_ids,
      call_status: "open",
      caller_phone: original_call.caller_phone,
      transfer_from_id: original_call.transfer_to_id,
      transfer_from_other: original_call.transfer_to_other,
      facility_from_location: original_call.facility_to_location,
      transfer_to_id: original_call.transfer_from_id,
      transfer_to_other: original_call.transfer_from_other,
      facility_to_location: original_call.facility_from_location,
      patient_name: original_call.patient_name,
      patient_age: original_call.patient_age,
      patient_dob: original_call.patient_dob,
      patient_sex_id: original_call.patient_sex_id,
      insurance_id: original_call.insurance_id,
      nature_id: original_call.nature_id,
      service_level_id: original_call.service_level_id,
      special_equipment_ids: original_call.special_equipment_ids,
      transfer_date: original_call.transfer_date,
      unit_ids: original_call.unit_ids,
      wait_return: "yes",
      parent_call_id: params[:id],

    )
  end

总而言之,我找到了一个半途而废的方法来限制仅在服务单位被调度到呼叫,但面临以下问题;

  1. 无法从通话中删除单位
  2. 编辑呼叫时,除非该单元处于服务状态,否则该单元不会显示在表单中。
  3. 创建返回调用时,它会将 unit_id 复制到 @call.unit_ids 中的一个数组中,因此该单元会在调用中显示两次。

因此,我希望能够在新呼叫中仅选择 In Service 单元,无论其状态如何,编辑时都会在表单中显示该单元,并且在返回呼叫时,只有 unit_ids 包含一个实例应该分配的unit_id。

我知道这确实令人困惑,并且很乐意与某人配对、聊天或构建一个 gist,以便您可以查看我的代码库。

非常感谢任何帮助,因为现在我正在碰壁。

更新:上午 10:44

我已尝试在单位数组上添加 .uniq,但问题仍然存在。我的辅助方法如下所示:

calls_helper.rb

 def unit_select
    (@call.units.to_a.uniq + Unit.active.in_service.order("unit_name")).map{|unit| unit.calls.where(call_status: "open").empty? ? ["#{unit.unit_name} #{unit.unit_type.unit_type}", unit.id] : ["#{unit.unit_name} (on call) #{unit.unit_type.unit_type}", unit.id] }
  end

这有意义吗?这是最好的方法吗?

【问题讨论】:

    标签: ruby-on-rails-3 forms activerecord scope


    【解决方案1】:

    我试图完全理解你的问题,但我必须说我有点困惑。您是否尝试过在 unit_select 中分离每个案例而不是尝试获得完美的一个衬里?据我了解,您希望能够选择:

    1. 当表单中的调用是新实例时,仅“服务中”单元
    2. 编辑现有呼叫时显示任何单位

    现在,正如我所说,我不确定我是否理解您的问题,但看起来您正在尝试做类似的事情:

    def unit_select
      units = Unit.active.in_service.order("unit_name")
      if !@call.new_record?
        units += @call.units
      end
      format_unit_select_options(units.uniq)
    end
    
    def format_unit_select_options(units)
      units.map do|unit|
        if unit.calls.where(call_status: "open").empty?
          ["#{unit.unit_name} #{unit.unit_type.unit_type}", unit.id]
        else
          ["#{unit.unit_name} (on call) #{unit.unit_type.unit_type}", unit.id]
        end
      end
    end
    

    你也应该搬家

    Unit.active.in_service.order("unit_name")
    

    在 Call 控制器的 new 和 edit 操作中,确保助手和控制器的职责更易于理解。

    现在,当您在 call_controller 中创建回呼时,您是否尝试在 original_call.unit_ids 上使用 uniq 以确保 id 仅存在一次?这可能只能解决症状而不是根本原因,但我无法完全理解您的情况......

    希望对你有帮助。

    【讨论】:

    • 马克,感谢您的帮助方法。这更干净,更接近我需要它做的事情。所以让我澄清一下。当一个新的调用实例时,它应该只显示状态为 In Service 的单元。编辑呼叫时(如果您想放置多个单元),它应该显示当前分配的单元(无论其状态如何)以及在需要时添加的服务单元列表。我尝试使用您的代码,在回电时,我不再获得两次分配的单元 ID。我认为我们在正确的轨道上。如果我的情况难以理解,我很抱歉,也许我们可以结对吗?
    • 让我们试着在这周找点时间配对。你会在推特上找到我:@mlainez
    • 谢谢,非常感谢!我会把你加到推特上。 @jamesjelinek
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多