ruby-prof shoots down my helper block
Here is the head of my ruby-prof output. I'm surprised to see that one of my fairly simple helper methods (ApplicationHelper#highlight_my) is topping the charts of the expensive procedures list.
18.67 0.27 0.27 0.00 0.00 237 Proc#binding 17.61 0.25 0.25 0.00 0.00 10208 WIN32OLE#method_missing 13.05 0.19 0.19 0.00 0.00 96 ApplicationHelper#highlight_my
All it does is slap a span tag around any task that belongs to the logged in user.
<% highlight_my(task.assignee) do %>
...
<% end %>
The span tag has a css class that will highlight those tasks.
def highlight_my(obj, &block)
if obj != nil
mine = obj.id == current_user.id
end
concat('<span class="mine">', block.binding) if mine
block.call
concat('</span>', block.binding) if mine
end
It appears the block binding might be a bit much overhead for such a simple operation. Perhaps a better use for it would be to wrap something more significant like a table to add rounded corners. You may only need to do this a handful of times rather than invoking the method 96 times like I did here. I still really like the syntax so i my play around with some different kinds of partial caching schemes to see if i can keep this in my bag of tricks.
Acts_As_Ferret Indexing on Model Reloads
I've been using spec_server to run tests as I develop and noticed that each time that my tests run it would take just a bit longer run. Right about the same time I was alerted by a file system error about a file being locked. It happened to be in the ferret indexing play yard where there were gobs of files.
No prob, I thought. I put a remove_dir routine in my spec helper and it cleared out the index files without a hitch. But my run times were still increasing.
So it appears that AAF likes to auto-index when its gets initialized and during development it gets reloaded often. There is a class method in AAF called disable_ferret but by the time I am able to use this method the indexing has already taken place.
For a short term hack I decided I wanted my tests to run faster so I dumped AAF while using spec_server which runs is test mode. I perform my testing on ferret during integration testing in a different mode so I don't need to worry about toggling this line off and on and worry about whether it will be there when it is released.
There is already ticket in the trac system for this. Till then here is what I've got.
acts_as_ferret :fields => {...} unless RAILS_ENV == 'test'
know thy collection helpers
Are you tired of seeing blog posts that takes a familiar chunk of code and turns it into a one liner? Neither am I, how could you possibly be. This weeks installment comes from a situation where i have task lists and tasks in the usual parent-child relationship. For reasons not explained here I have a list of tasks that reference their own copy of their task list parent. So now I am wanting to collect a unique set of the task lists.
Here is what I came up with
def self.collect_unique_parents(tasks)
task_lists = []
tasks.each do |task|
task_list = task.task_list
task_lists << task_list unless task_lists.include?(task_list)
end
task_lists
end
task_lists = collect_unique_parents(tasks)
But I decided to consult the available collection helpers and realized that group_by would be a good fit for this case. Also symbol-to-proc is thrown in for good measure.
task_lists = tasks.group_by(& :task_list).keys
However, beware that this will mess up any sort ordering because the group_by is hashing the results and I'm just pulling them back out with #keys.
a visual tour of some active record associations
I have been sitting in my office with drawings of active record associations hanging on my whiteboard behind me for quite a while. When I began learning about active record associations it was helpful to have something visual nearby for quick reminder. I decided to dump them into images using my pathetic Inkscape svg skills.
To clarify how these boxes are used you first need to know that the association method is describing what goes in the green box. I would have put the method inside of it but there wasn't always enough room. Also the back end dot of the arrow represents where the foreign sits. So in the case of belogns_to, the foreign key of the other class sits in the declarers own table. When you see the colored bars that refers to the :type column that stores the name of the target class. Having the colors match resembles having the types match.
The last one you can ignore as it is mostly a work in progress for how i've been hacking on has_many_polymorphs. That can be a topic for another day.





example: case note

example: something having case notes

example: tagging multiple types

example: milestone
observe this task closely
I have a number of task lists that each contains a number of tasks [one to many] that may be active or complete. If all of the tasks are complete then I want to mark the task list as complete. I would like to know which task lists are complete without having to perform a join on the task table and count them each time I load the index page.
Instead I will keep track of each time a task is created, deleted, changed from active to complete or changed from complete back to active state. Then I can just look for task lists that have an ‘active task count’ of 0.
It sounded tough at first and I tried a number of different ways but eventually came up with a way to do it in 26 lines of elegant code and touching only one file.
The amazing part (to me) is that code below is 100% complete and requires no changes to the to the TaskList class or the Task class which means that there is no worrying that someone will forget to update the task list count.
Also the entire thing can be turned off by commenting out the very last line “TaskObserver.instance” and nothing will break.
class TaskObserver < ActiveRecord::Observer
def after_initialize(task)
task.orig_complete = task.complete
end
def after_update(task)
if task.orig_complete != task.complete
if task.complete == true
task.task_list.decrement(:active_tasks_count).save
else
task.task_list.increment(:active_tasks_count).save
end
end
end
def after_create(task)
task.task_list.increment(:active_tasks_count).save
end
def after_destroy(task)
task.task_list.decrement(:active_tasks_count).save unless task.complete?
end
end
TaskObserver.instance
blank?
I have confused myself in the past when trying to use this method in the wrong places.
Using the method #blank? is useful but confusion can come from not knowing when it can be applied. For example rails adds the method for you so if you write a standalone ruby program it won’t be there unless you add it yourself. Also you may confuse having a nil object with not having an object. Example…
puts @a
puts b
This little script will choke on the second line since it is not defined. So while you can call methods on a nil class you cannot call methods on an undefined variable. Using the @ symbol will implicitly scope the variable as an object and give you a nil class if you don’t define it. So now when we do this.
puts @a.blank?
puts b.blank?
The first variable is a Nil object that supports the #blank? method but the second is undefined and will choke.
