# Loading part of a has\_many association, and sorting as I add more elements

**URL:** <https://www.ruby-forum.com/t/loading-part-of-a-has-many-association-and-sorting-as-i-add-more-elements/165840>\
**Category:** Rails\
**Created:** [April 18, 2009, 2:57am UTC](https://www.ruby-forum.com/t/loading-part-of-a-has-many-association-and-sorting-as-i-add-more-elements/165840 "2009-04-18T02:57:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![SeanWalberg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ccd318/32.png) [@SeanWalberg](https://www.ruby-forum.com/u/SeanWalberg)\
**Post date:** [April 18, 2009, 2:57am UTC](https://www.ruby-forum.com/t/loading-part-of-a-has-many-association-and-sorting-as-i-add-more-elements/165840/1 "2009-04-18T02:57:48Z")

</div>

Hello,

I have what boils down to a timesheet app. Before I display the entry  
form (eg one text input per day in the current schedule) I load the  
shifts I have in the database for the given period, then create new,  
blank shifts to fill in the blanks for the week before sorting the  
shifts by date and assigning to the relation.

This works in that if I have 2 shifts stored in the DB and want to  
display a week, the routine adds 5 more blank shifts and sorts.  
However, once I assign this to the relationship, the sorting seems to  
revert to created\_by rather than the sort order of the array I  
assigned (example below)

class Shift \< ActiveRecord::Base  
belongs\_to :employee  
end

class Employee \< ActiveRecord::Base  
has\_many :shifts, :order =\> “date ASC”

```
 def load_schedule(start, numdays)

    raise "numdays must be >=1" if numdays < 1
    # find the shifts that are already stored that are between

```

start and start+numdays  
currentshifts = Shift.find(  
:all,  
:conditions =\> [“employee\_id = :eid AND date \>= :start AND  
date \<= :finish”,  
{ :eid =\> self.id,  
:start =\> start.at\_beginning\_of\_day,  
:finish =\> start.at\_beginning\_of\_day  
+numdays.days-1.second  
} ] )

```
     newshifts = Array.new
     # iterate through the week and create new shifts for the days

```

that are missing  
# code omitted

```
     # debugging stuff
     puts "============================================"
     c = newshifts.to_a + currentshifts.to_a
     puts "unsorted"
     c.each { |s| puts "#{s.date} - #{s.hours}" }
     d = c.sort_by { |a| a.date }
     puts "sorted"
     d.each { |s| puts "#{s.date} - #{s.hours}" }
     self.shifts = d
     puts "in employee object"
     self.shifts.each { |s| puts "#{s.date} - #{s.hours}" }

```

end

The results of this are:  
.============================================  
unsorted  
2009-02-25 -  
2009-02-26 -  
2009-02-28 -  
2009-03-02 -  
2009-03-03 -  
2009-02-27 - 1.5  
2009-03-01 - 1.5  
sorted  
2009-02-25 -  
2009-02-26 -  
2009-02-27 - 1.5  
2009-02-28 -  
2009-03-01 - 1.5  
2009-03-02 -  
2009-03-03 -  
in employee object  
2009-02-27 - 1.5  
2009-03-01 - 1.5  
2009-02-25 -  
2009-02-26 -  
2009-02-28 -  
2009-03-02 -  
2009-03-03 -

The reason I’m sorting and adding the blank shifts in the model is  
because I’m passing the object back up to the view where I’m using the  
FormHelpers to create the form. I’m loading a subset of the shifts at  
a time because it seems wasteful to load a year’s worth of timesheet  
data if I’m only working with a week.

Why/how is the Array getting resorted when I assign it to the  
association? How do I stop it?  
Should I be working with a subset of the shift data this way, or is  
there a better way?  
Am I going about this completely wrong?

Thanks,

Sean

---

<div class="post-metadata">

**Author:** ![SeanWalberg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ccd318/32.png) [@SeanWalberg](https://www.ruby-forum.com/u/SeanWalberg)\
**Post date:** [April 18, 2009, 3:11am UTC](https://www.ruby-forum.com/t/loading-part-of-a-has-many-association-and-sorting-as-i-add-more-elements/165840/2 "2009-04-18T03:11:18Z")

</div>

On Apr 17, 7:12 pm, SeanWalberg [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Why/how is the Array getting resorted when I assign it to the  
> association? How do I stop it?

The key bit is the replace method in

> <https://github.com/rails/rails/blob/70de8e64e30092b2b1b77869e459b4868f5b9577/activerecord/lib/active_record/associations/association_collection.rb>

It’s trying to minimise the number of delete or updates to the  
database, so it first removes all the records that should no longer be  
there, then appends all the records that need to be added to the  
collection, which will mess with your order if the collection is non  
empty to begin with

If you reload the association the records should come out in the right  
order

Fred

---

<div class="post-metadata">

**Author:** ![SeanWalberg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ccd318/32.png) [@SeanWalberg](https://www.ruby-forum.com/u/SeanWalberg)\
**Post date:** [April 18, 2009, 4:38pm UTC](https://www.ruby-forum.com/t/loading-part-of-a-has-many-association-and-sorting-as-i-add-more-elements/165840/3 "2009-04-18T16:38:39Z")

</div>

On Apr 17, 8:10 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> It’s trying to minimise the number of delete or updates to the  
> database, so it first removes all the records that should no longer be  
> there, then appends all the records that need to be added to the  
> collection, which will mess with your order if the collection is non  
> empty to begin with
> 
> If you reload the association the records should come out in the right  
> order

self.shifts = (newshifts.to\_a + currentshifts.to\_a).sort\_by { |a|  
a.date }

# Reload to get them in order

self.shifts.reload

That seems to work (or at least passes my test cases 😉 ), thanks a  
lot!

Sean
