I am new to Ruby, and working on code written by someone else. We are having to work with deprecated versions: Ruby 1.8.7, and Rails 2.3.5 - because this is a charity in the developing world and there is no capacity to upgrade.
I have a report which produces a table (a drug inventory), and need to sort it by the drug's name.
The relevant controller code looks like this:
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
}
The relevant view code looks like this:
<%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
}%>
This happily produces the correct table but in a random order (re-starting the server and reloading the page will give the table in a new order).
I have tried a variety of options found online. I tried @stock.all.order (doesn't work in Rails 2.x), @stock.find (doesn't accept 2 arguments, :all and :order, and using just :order doesn't help), @stock.sort (no effect), and @stock.sort_by (no effect). All of those placed either at the end of the controller code or just before the @stock.each in the view code.
I have to say I am particularly baffled that the order is random - I would have presumed that even if I was failing to order it by name, the order would still be consistent...
Any help would be very much appreciated!
.sortand.sort_byon @stock - I'll update the question to clarify that. I tried a simple @stock.sort, as well as some variations such as@stock.sort_by { |a| a[0] }, and@stock.sort{|a,b| b[:name] <=> a[:name]}, based on other answers I'd found on this site. None worked, but of course I may have got the syntax wrong. In particular I am not confident that I fully understand the structure and indexing of the @stock array.@stockis not an array. It is an instance variable, that was declared as a Hash:@stock = {}. You probably want to@stock.sort_by { |k,v| v }, or just@stock.keys.sort.each { |k| }