Preserving has_many order

My application will need to store many measurements (eg: temperature) for a set of locations (eg: roof) and periodically recall those measurements for charting, browsing, or editing.

class Location < ActiveRecord::Base   has_many :Measurements end

class Measurement < ActiveRecord::Base   belongs_to :Location end

I would like the measurements to be kept in the order in which they are taken and stored in the database so that a potentially expensive sorting operation is not required every time the user queries a location's temperature history.

If I implemented this with a linked list, I would add new temperature measurements to the head and traverse down the list as needed for a deterministic retrieval. Will Rails perform a conceptually similar operation and store/retrieve Measurement instances in a determinsitic manner? If not, are there any recommendations for preserving order in a has_many relationship?

Thanks! Mark

You should add an order clause to your has_many, without one the database is free to return rows in any order it pleases. This shouldn't be a performance issue as long as you have appropriate indexes in place.

Fred

Frederick Cheung wrote:

Robert Walker wrote:

Frederick Cheung wrote:

a has_many relationship?

You should add an order clause to your has_many, without one the database is free to return rows in any order it pleases. This shouldn't be a performance issue as long as you have appropriate indexes in place.

There is a plugin that simplifies the implementation of what is described in the OP. I have no idea whether this plugin is still a viable solution. There may be newer ones that replace its functionality. But, I think it's still worth taking a look at for ideas:

GitHub - rails/acts_as_list: NOTICE: official repository moved to https://github.com/swanandp/acts_as_list

That's what I'd use. It's simple and seems to work well.

Best,

Thanks everyone for the recommendations. :order looks like an easy way to get started. I'll go with that and see if any optimizations are needed down the road.

MarkB wrote:

Thanks everyone for the recommendations. :order looks like an easy way to get started. I'll go with that and see if any optimizations are needed down the road.

On Feb 2, 12:37�am, Frederick Cheung <frederick.che...@gmail.com>

The question is, "what to order by?" You can't truly depend on ordering by an auto-generated primary key. That might work in some databases, but certainly not for all. Even with databases that do seem to keep records in order by a simple incrementing integer primary key, there is no guarantee.

You might think then that ordering by the created_at date could be an option. However, that's risky too. Ordering could easily be corrupted by changes to the system clock.

Something like acts_as_list maintains a separate :position column in the database that can be used to both ensure proper ordering as records are created, and allows for reordering of the list when (or if) necessary.

Robert Walker wrote:

Something like acts_as_list maintains a separate :position column in the database that can be used to both ensure proper ordering as records are created, and allows for reordering of the list when (or if) necessary.

Come to think of it, this brings up an interesting question. Does any know if acts_as_list is subject to race conditions when assigning/maintaining the position attribute?

Robert Walker wrote:

Robert Walker wrote:

Something like acts_as_list maintains a separate :position column in the database that can be used to both ensure proper ordering as records are created, and allows for reordering of the list when (or if) necessary.

Come to think of it, this brings up an interesting question. Does any know if acts_as_list is subject to race conditions when assigning/maintaining the position attribute?

I doubt it. All AR saves and updates are transactional.

Best,

Even with databases that do seem to keep records in order by a simple incrementing integer primary key, there is no guarantee.

Can you explain this a little further?

Milan Dobrota wrote:

Even with databases that do seem to keep records in order by a simple incrementing integer primary key, there is no guarantee.

Can you explain this a little further?

Well, the counter could always get reset. But there's an important principle here: the value of a surrogate key should never be meaningful. You should be able to replace all your primary keys with, say, GUIDs and have your app keep working.

Best,