Please help me understand.. date not sorting correctly

I am new to Ruby and Rails, but have extensive background with php/SQL…
I am working on my first Ruby project to dive into the framework and
learn. I am building an internal time tracking app. I have a table of
jobs, tasks and timelogs.

Timelogs belongs_to :task, task belongs_to :jobs and has_many :timelogs,
jobs has_may :tasks and has_many :timelogs :through => :tasks

When pulling all of this data into a detail table i want to sort by the
task and then by the timelog log_date.

JOB1
th: task1
tr: child timelogs sorted by log_date

th: task2
tr: child timelogs sorted by log_date

My code will sort by the tasks fine, but will not sort by the
timelog.log_date no matter what i’ve tried.

Here is part of my job.rb:
class Job < ActiveRecord::Base

create relationships

has_many :tasks
has_many :timelogs, :through => :tasks

my action:
def detailsTable
@job = Job.find(params[:id], :include => [:tasks, :timelogs], :order
=> ‘tasks.description, timelogs.log_date’ )
end

and my table:
<% for task in @job.tasks %>

<% for timelog in task.timelogs %> <% end %>
<%=h task.description %>
<%=h timelog.log_date.strftime("%b %d") %> <%=h timelog.hours %> hours <%=h timelog.description %>
<% end %>

Any help would be appreciated as I am in need of some clues to this date
sorting issue. It it probally something in the model that I don’t
understand.

cheers,
nick

development.log will show you the actual SQL queries which may provide
more insight.

K… looking at the development log the SQL query appears to be fine, but
when my view is rendered there is a database query for each task in the
job.

e[4;36;1mTimelog Load (0.000515)e[0m e[0;1mSELECT * FROM timelogs
WHERE (timelogs.task_id = 12) e[0m
e[4;35;1mTimelog Load (0.000461)e[0m e[0mSELECT * FROM timelogs
WHERE (timelogs.task_id = 9) e[0m
e[4;36;1mTimelog Load (0.000290)e[0m e[0;1mSELECT * FROM timelogs
WHERE (timelogs.task_id = 11) e[0m
e[4;35;1mTimelog Load (0.000311)e[0m e[0mSELECT * FROM timelogs
WHERE (timelogs.task_id = 10) e[0m
e[4;36;1mTimelog Load (0.000375)e[0m e[0;1mSELECT * FROM timelogs
WHERE (timelogs.task_id = 8) e[0m

That explains why they aren’t sorted. I see that now.

But why are there calls to the db inside of the nested <% for timelog in
task.timelogs %> loop and not the outer <% for task in @job.tasks %>
one. I was trying to minimize the database calls and the my :job symbol
seems to have everything in it from the originall call.

I can change it do do multiple queries, but i still don’t understand why
the db is being queried again when all the info is seemingly available.

Like i said, I am a rails virgin… Any info is appreciated.

thanks

Taylor S. wrote:

add <%= debug(@job) %> to your view. This will let us know if
ActiveRecord is really pulling all the data into your instance variable
in the first query.

did it.

It is showing that everything is being loaded on the first query.

Is there something about this nested for that would make it
automatically query the db again for the second one? Is there a
different way to call the :task symbol in the first or second for that
would make it act different?

@job = Job.find(params[:id], :include => [:tasks, :timelogs], :order =>
‘tasks.description, timelogs.log_date’ )

<% for task in @job.tasks %>

<% for timelog in task.timelogs %>

Am i just not understanding how rails works? It seem that it should
have to query a second time in the nested for loop when all the data is
loaded.

thanks

add <%= debug(@job) %> to your view. This will let us know if
ActiveRecord is really pulling all the data into your instance variable
in the first query.

job = Job.find(params[:id], :include => [:tasks => :timelogs]

Try that. Note the ‘=>’ denoting the relationship between tasks and
timelogs.

Ading the ‘=>’ in the include didn’t help…
Here is my (hopefully temporary) workaround… i am defining the @timelog
symbol inside of the view within the first for loop.

<% for task in @job.tasks %>

<% @timelogs = Timelog.find(:all, :conditions => [‘task_id = ?’,
task.id], :order => ‘log_date’) %>
<% for timelog in @timelogs %>

<% end %>
<% end %>

I think there should be a more elegant way, i just am stumbling through
this right now. It seems that no matter what, according to the
development.log, the nested for loop would always spawn a db query for
each iteration. So i made another symbol to loop through so i could set
the sort order.

I’m am still open for any suggestions, tips, pointers, anything… again
I’m just starting out.

Thanks for the help

nick

disregard my last post…

adding the ‘=>’ in the include like you suggested did in fact work.

So now my contoller reads as this

@job = Job.find(params[:id], :include => [:tasks => :timelogs], :order
=> ‘tasks.description, timelogs.log_date’ )

and my nested for loops are working without calling additional db
queries and everything is being sorted correctly.

Thank you.