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
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.
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?
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.
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.
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.