开发者

Default Logical Sort on Resultset Array RubyonRails

I've add a custom sort to an ActiveRecord model by defining a method like this:

class MyClass < ActiveRecord::Base
  belongs_to :parent_model #this would be the many in a has_many relationship

  def <=>(other)
    self.att <=> other.att
  end
end

Suffice it to say, the logic actually being employed in the comparison is a bit more complex than this example, and is not something that can be accomplished with SQL.

Because this class is only used as nested fields in an encompassing model, there doesn't seem to be a straight-forward place to sort the result set. In the controller, :my_class is a part of the include for eager loading, but I don't do anything else with the object array until the view (when I do form.fields_for :my_class). What I really want is to be able to do the equivalent of default_scope using my logical sort, but I don't t开发者_如何学Pythonhink that's possible. Right now, my only option seems to be adding an extra line in the controller just to do the sort on this result, but that doesn't seem like it's the right thing to do.

Is there something more elegant I'm missing here?


The hands down best way to do this is to set up your database for SQL sorting and give an :order option in your scopes/finds. Doing the sort in the controller is going to be very costly once the number of objects loaded passes a certain threshold. Especially if you're trying to limit the number of records listed.

If the sort really is more complicated than sort this column than that one. You should consider adding a sort key column to the database. You've clearly worked out some method of ordering things, usually that involves comparing two values derived from the state of the object. Just store that value in the database in the new sort_key column with a before_create/save callback and order results by that.

Task Example:

Ordered by priority, but records where due date is a Friday, are listed before all others. Uses a sort_key column

class Task < ActiveRecord::Base
  def calculate_sort_key
    key = due_date.wday == 5 ? "0" : "1"
    key += prioirty.to_s
    self.sort_key = key.to_i
  end

  before_save :calculate_sort_key
  default_scope :order => "sort_key"
end


I haven't been able to test if this would work, but you could try an anonymous association module, like this:

class ParentModel < ActiveRecord::Base
  has_many :my_class do
    # Sort the result set...  
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜