【问题标题】:Ruby-on-Rails - Problems displaying a sorted tableRuby-on-Rails - 显示排序表的问题
【发布时间】:2016-06-01 08:10:32
【问题描述】:

我是 Ruby 新手,正在处理其他人编写的代码。我们不得不使用已弃用的版本:Ruby 1.8.7 和 Rails 2.3.5 - 因为这是发展中国家的慈善机构,无法升级。

我有一个生成表格(药物清单)的报告,需要按药物名称对其进行排序。

相关的控制器代码如下所示:

all_drugs = Drug.find(:all,
                      :order => "name ASC")
@stock = {}
all_drugs.each{ |drug|
  drug_id = drug.drug_id
  first_date = Pharmacy.active.find(:first,
                                    :conditions =>["drug_id =?",drug_id],
                                    :order => "encounter_date").encounter_date.to_date rescue nil
  next if first_date.blank?
  next if first_date > @end_date

  start_date = @start_date
  end_date = @end_date

  stock_at = Pharmacy.stock_at(drug_id,end_date)
  if stock_at > 0
    last_activity = "In stock"
    else last_activity = Pharmacy.last_activity(drug_id,end_date)
  end

  drug = Drug.find(drug_id)
  drug_name = drug.name
  @stock[drug_name] = {"dispensed" => 0,"stock_at" => 0,"removed" => 0, "receipts" => 0,"prescribed" => 0,"last_activity" => 0}
  @stock[drug_name]["dispensed"] = Pharmacy.dispensed_drugs_since(drug.id,start_date,end_date)
  @stock[drug_name]["stock_at"] = stock_at
  @stock[drug_name]["removed"] = Pharmacy.total_removed(drug.id,start_date,end_date)
  @stock[drug_name]["receipts"] = Pharmacy.total_delivered(drug.id,start_date,end_date)
  @stock[drug_name]["prescribed"] = Pharmacy.prescribed_drugs_since(drug.id,start_date,end_date)
  @stock[drug_name]["last_activity"] = last_activity
}

相关视图代码如下:

<%count = 1
@stock.each{|name,values|
  prescribed = values["prescribed"]
  receipts = values["receipts"]
  dispensed = values["dispensed"]
  removed = values["removed"]
  stock_at = values["stock_at"]
  last_activity = values["last_activity"]
%>

  <tr>
    <td class="color_<%=color%>"><%=name%></td>
    <td class="color_<%=color%> caldata" id="stock_at_<%=count%>"><%=stock_at%></td>
    <td class="color_<%=color%> caldata" id="removed_<%=count%>"><%=removed%></td>
    <td class="color_<%=color%> caldata" id="prescribed_<%=count%>"><%=prescribed%></td>
    <td class="color_<%=color%> caldata" id="dispensed_<%=count%>"><%=dispensed%></td>
    <td class="color_<%=color%> caldata" id="last_activity_<%=count%>"><%=last_activity%></td>
    <td class="color_<%=color%> caldata" id="receipts_<%=count%>"><%=receipts%></td>
  </tr>
  <% count+=1
}%>

这很高兴生成正确的表格,但顺序是随机的(重新启动服务器并重新加载页面将使表格以新的顺序出现)。

我尝试了网上找到的各种选择。我试过@stock.all.order(不适用于Rails 2.x),@stock.find(不接受2个参数,:all:order,只使用:order没有帮助),@987654328 @(无效)和@stock.sort_by(无效)。所有这些都放置在控制器代码的末尾或视图代码中的 @stock.each 之前。

我不得不说我特别困惑的是订单是随机的 - 我会假设即使我没有按名称订购,订单仍然是一致的......

任何帮助将不胜感激!

【问题讨论】:

  • 你试过 .sort 吗?
  • 是的,谢谢,我在@stock 上尝试了.sort.sort_by - 我会更新问题以澄清这一点。我尝试了一个简单的@stock.sort,以及一些变体,例如@stock.sort_by { |a| a[0] }@stock.sort{|a,b| b[:name] &lt;=&gt; a[:name]},基于我在此站点上找到的其他答案。没有奏效,但当然我可能语法错误。特别是我不确定自己是否完全理解 @stock 数组的结构和索引。
  • @stock 不是数组。它是一个实例变量,被声明为 Hash:@stock = {}。你可能想@stock.sort_by { |k,v| v },或者只是@stock.keys.sort.each { |k| }
  • 感谢您为我澄清,我错过了这一区别!不幸的是,这些解决方案都不起作用。

标签: ruby-on-rails ruby html-table


【解决方案1】:

根据 ruby​​ 1.8.7 中的定义,哈希是无序的(请检查Ruby 1.8: Hash#sort not return hash but array (better way to do this?)),因此我们必须将顺序用作数组。不可能有排序哈希之类的东西。在你看来换行

@stock.each{|name,values|

@stock.sort_by {|s, v| s.downcase}.each{|name,values|

【讨论】:

  • 谢谢,但这并没有什么不同 - 列表仍未排序。
  • 你能转储“@stock”变量并将前 3 行发送给我吗,“puts @stock”
  • 转储的开始看起来像这样(当然是虚拟数据): {"Paracetamol (250mg)"=>{"receipts"=>10000.0, "prescribed"=>0, "dispensed"= >0, "last_activity"=>"In stock", "removed"=>0, "stock_at"=>10000.0}, "扑热息痛 (1g)"=>{"receipts"=>10000.0, "prescribed"=>0 , "dispensed"=>0, "last_activity"=>"In stock", "removed"=>0, "stock_at"=>10000.0}, "EFV (Efavirenz 600mg tablet)"=> N.B.我重新加载了服务器几次,每次药物的顺序都不同。
  • 请尝试哈希[@stock.sort_by {|s, v| s.downcase}].each{|名称,值| -- 不要忘记在|s, v|中添加v
  • 我怀疑在创建另一个哈希时,ruby 1.8.7 中无序哈希的问题仍在视图中生成“随机”药物顺序。
【解决方案2】:

Ruby 1.8.7 中的哈希没有排序,因此您不能依赖 @stock 中键的顺序。

作为一种解决方法,首先我会查询 Drug 仅选择 idname 字段

all_drugs = Drug.find(:all, :select => "id, name")

当您稍后在代码中查询单一药物属性时。

然后我会创建一个空的@stock_keys 数组来收集药物名称,就在@stock 哈希定义之后

@stock = {}
@stock_keys = []

并在您查询 drug_id 之后将药物名称推入其中

drug = Drug.find(drug_id)
drug_name = drug.name
@stock_keys << drug_name 
@stock[drug_name] = ...

all_drugs 的迭代结束时,在您的控制器中,我会对 @stock_keys 数组进行排序

@stock_keys.sort!

然后,在视图中,我将遍历 @stock_keys 数组,在每一步从 @stock 哈希中检索药物的值

 @stock_keys.each do |name|
    values = @stock[name] 
    prescribed = values["prescribed"]
    ...
 end

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2017-04-20
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    相关资源
    最近更新 更多