Jerome
Jerome

Reputation: 6189

ruby (for rails) sort_by instantiated variable

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

Answers (2)

BroiSatse
BroiSatse

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

Uri Agassi
Uri Agassi

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

Related Questions