Reputation: 6189
In a rails 3.2.17 application, with ruby 1.9.3, a method filters a previously-found set of products based on a condition. If it passes the condition, it creates an instance variable for the record (rate), which itself is the product of another method (shown_price).
@products = @inventories.map(&:product).uniq
def validarray
validarray = Array.new
@products.each do |product|
@inventories_for_product = @inventories.select{ |i| i.product_id == product.id }
if @inventories_for_product.count == @threshhold
product.rate = @inventories_for_product.map(&@shown_price).inject(0, :+)
validarray << product
end
end
validarray.sort_by{|p| p[:rate]}
end
@validarray = validarray
All elements in this method generate proper data which can be viewed via the browser. In fact (even re-calling sort_by)
<% @validarray.sort_by{|p| p[:rate]}.each do |vp| %>
<%= vp.id %> <%= vp.rate %><br />
<% end %>
will show the proper data.
Issue when I ask for descending order
@validarray.sort_by{|p| -p[:rate]}
undefined method `-@' for nil:NilClass
whereas for ascending order no complaints, but no sorting either.
I assume that the symbol :rate is wrong and ruby lets the stuff unsorted as ASC is invoked by default and has nothing to sort with, but complains otherwise because it has no tools in its hands.
Upvotes: 0
Views: 1230
Reputation: 44685
Most likely yourate
attribute is not a column in products
table, but it is defined as a method within Product
model. This means that []
method on the model will always return nil
, as it only reads given database column and perform a typecast. In short, do:
@validarray.sort_by &:rate
or (in reverse order)
@validarray.sort_by{|p| -p.rate }
Upvotes: 2
Reputation: 37409
Possibly not all products have a :rate
value. You could either:
@validarray.sort_by{|p| p[:rate]}.reverse
or:
@validarray.sort_by{|p| -(p[:rate] || 0) }
Upvotes: 2