1

I am trying to sort a set of object s, where s class has an instance method called some_method defined in Model of S that returns a value v.

def some_method(id)
  ...
  return something # a float number
end 

Class S is related to class C with many_to_many relation. (class C has_many s and class S has_many c). I get this set of s objects by calling C.find(c_id).s

I am trying something like this

C.find(c_id).s.sort{|a,b| a.some_method(id) <=> b.some_method(id)}

but I fail to sort the array. How am I supposed to do this?

leoluo
  • 249
  • 1
  • 2
  • 8
  • Does it work if you rename the method `method`? I think you may be overridding the built-in `method` method, which could have unintended side-effects: http://ruby-doc.org/core-2.2.3/Object.html#method-i-method – Unixmonkey Nov 02 '15 at 23:37
  • It is not called "method", sorry for confusion – leoluo Nov 02 '15 at 23:42
  • is you method really a class method? or a normal instance method? – Meier Nov 03 '15 at 00:17
  • Changed that, sry for confusion – leoluo Nov 03 '15 at 00:25
  • What is the error that you encounter? If not, what is the (simplified) input given and what result does it return? – linkyndy Nov 03 '15 at 08:09
  • no error occurs, but the sort has no effect. Say for example I sort a group of users selected from database, order by user_id in ascending order, after calling sort on users the result is still order by user_id in ascending order – leoluo Nov 03 '15 at 08:20
  • I've tried a similar query with my current setup and it sorts the collection accordingly. I believe you're aware that your sorting is not in place, right? Also, where does `id` come from? You can also check the output of `C.find(c_id).s` by appending `.map { |obj| obj.some_method(id) }`, then compare it with the output of your sorting by appending the same `map` as before. This is just to be sure the collection _really_ didn't change. – linkyndy Nov 03 '15 at 11:39

1 Answers1

0

You're using the <=> operator but seem to be returning floats. That's not what that operator needs to sort effectively. (Read more about that operator here)

I suggest you use sort_by

C.find(c_id).s.sort_by{ |element| element.some_method(id) }

This will sort the array s on the method some_method, assuming you have an id that you pass in. Depending on what id is, you might need to define it outside this block.

Community
  • 1
  • 1
yez
  • 2,368
  • 9
  • 15
  • this is not working... well to be more specific, class S is related to class C with a many_to_many relationship. I get this ArrayOfS by calling C.find(c_id).s (class C has_many s and class S has many c). Will that be different? – leoluo Nov 03 '15 at 00:19
  • Could you paste your S and C classes in the original question and I'll update my answer to help? – yez Nov 03 '15 at 00:22