Friday, 6 February 2009

BackgroundRb and Synchronous calls

BackgroundRb lets you also call the workers synchronously. This is quite neat as you can use it as a form of pseudo-proxy and all other kinds of goodies.
But, the documentation is lacking, so I am posting this for all you frustrated Googlers out there. Here is what you need to do.

class SampleWorker < BackgrounDRb::MetaWorker
set_worker_name :sample_worker

def create(args = nil)
# this method is called, when worker is loaded for the first time
end

def test_me args
puts "test_me 1 (puts)"
logger.debug("test_me hit (log)")
return "of course it works"
end
end


Now, the BackgroundRb site tells you to call this like so to get a response back:

MiddleMan.worker(:sample_worker).test_me(:arg => "1")


This, in fact, won't work.

You need to do this:

MiddleMan.worker(:sample_worker).test_me({:arg => "1"}, true)


The second parameter (and make sure you put {} around your first set of args) is some freaky boolean to say, "no, seriously, I want a result back". Otherwise you get nil.

Bonus Tip!
When you define a method in a worker it HAS to accept arguments.
This won't work:
def test_me
end


This will:

def test_me(something = 1)
end

Friday, 16 January 2009

Rails and eTags

In the never ending search for speed I've been doing a lot of stuff with 304 Conditional get's. Here is a good article about etags - which is a vital component to it!


Rails-ETags

Friday, 12 December 2008

MySQL and Leopard

I had such problems on my macbook (though not on the macpro) in getting mysql running.

This article seems to have helped.

Monday, 8 December 2008

checkboxes for multiple items

I am doing an interface where I want to list a bunch of things (index) and have a checkbox next to each of them. Then, using a button, edit or show all those selected items.
I am always running into this problem of checkboxes (maybe I am just stupid) so I spent some time and figured out a way that works for me. There are probably other solutions, but here is what I do:

First, in the index.html I have this javascript code:

<% content_for :javascript do %>
<script type="text/javascript" charset="utf-8">
/* <![CDATA[ */
function editDevices() {
var device_count = document.getElementsByName('device[]').length;
var total="";
for(var i=0; i < device_count; i++){
if(document.forms['group_edit'].elements['device[]'][i].checked) {
if (total.length > 0) {
total += ","
}
total +=document.forms['group_edit'].elements['device[]'][i].value;
}
}

new Ajax.Request('<%= group_edit_devices_path %>', {
parameters: {
authenticity_token: encodeURIComponent('<%=form_authenticity_token%>'),
device_ids: total
}
}
);
}

function showDevices() {
var device_count = document.getElementsByName('device[]').length;
var total="";
for(var i=0; i < device_count; i++){
if(document.forms['group_edit'].elements['device[]'][i].checked) {
if (total.length > 0) {
total += ","
}
total +=document.forms['group_edit'].elements['device[]'][i].value;
}
}

new Ajax.Request('<%= group_show_devices_path %>', {
parameters: {
authenticity_token: encodeURIComponent('<%=form_authenticity_token%>'),
device_ids: total
}
}
);
}
/* ]]> */
</script>
<% end %>


Then I have the table of devices:

<table border="0" cellspacing="5" cellpadding="5">
<thead>
<tr>
<th>&nbsp;</th>
<th>Uid</th>
<th>Name</th>
<th>Ip</th>
<th># Displays</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="5">
<ul class="tabs">
<li><%= link_to_function "Show", "showDevices()" %></li>
<li><%= link_to_function "Edit", "editDevices()" %></li>
<li><%= link_to "Delete" %></li>
</ul>
</td>
</tr>
</tfoot>
<tbody>
<% for device in @devices %>
<tr>
<td><%= check_box_tag("device[]", device.id, false, :id => "device_#{device.id}") %></td>
<td><%=link_to_remote h(device.uid), :url => formatted_device_path(device, :js), :method => "get" %></td>
<td><%=h device.name %></td>
<td><%=h device.ip %></td>
<td><%= device.displays.count %></td>
</tr>
<% end %>
</tbody>
</table>


The result is that my ajax function will be called with a comma separated list of the ids of the selected devices.

Thursday, 27 November 2008

&@$%^£& IE 7 and insecure content!

What a morning!

A user kindly reported that he couldn't log in to FilmAmora using IE7. IE6 worked, FireFox worked. Safari worked.

IE7 (for me) was coming up first with the 'there is insecure content on this page do you wish to show it?' (the login in page is under https). Clicking yes or no had the same result: the page would flash but then IE7 reported that it couldn't show the page. (It should have, it turns out, said 'I am choosing not to show the page').

The issue was that insecure content. For me, specifically it was the statcounter call. But your issue may be other calls. Anyway, I removed all calls to anything outside of my domain and that seems to have fixed it!

Monday, 3 November 2008

unfuddle

I use unfuddle as a git host and bug tracking, etc service. But, because I have so many projects on the go I ran into this problem where you can only have an ssh key in ONE account on unfuddle. So, I wrote to the support guys and asked them how to handle multiple accounts from one machine.
Here is their response:

The easiest way to deal with need multiple keys for multiple accounts is to actually just create them using different filenames in your ~/.ssh/ directory. For instance, if you have 2 accounts, "account1" and "account2", you would want to run "ssh-keygen -t rsa" twice, each time specifying a different filename:

~/.ssh/unfuddle_account1_id_rsa
~/.ssh/unfuddle_account2_id_rsa

Now, by default, ssh will use the file ~/.ssh/id_rsa when connecting to a remote server. As neither of your keys is in this file, you must tell SSH (not git) which private keyfile to use when connecting to each account. This is done using the SSH config file.

For instance, create or edit a file named .ssh/config with the following contents:


Host account1.unfuddle.com
User git
IdentityFile ~/.ssh/unfuddle_account1_id_rsa

Host account2.unfuddle.com
User git
IdentityFile ~/.ssh/unfuddle_account2_id_rsa


I have followed this model for my own accounts (of which I have many) and it has worked perfectly. I hope this helps you as well.

Thursday, 16 October 2008

Creating a summary

I have an app that has rows of statistics. We wanted to create summaries of arbitrary rows.
This method seems to work:

  def self.create_summary_row(array)
unless array.blank?
klazz = array.first.class
sum_stat = klazz.new
array.each do |line|
if line.is_a?(klazz)
line.attributes.each do |k,v|
unless v.nil? || v.is_a?(Time) || v.is_a?(Date)
if sum_stat[k].nil?
sum_stat[k] = v
else
sum_stat[k] += v
end
end
end
end
end
sum_stat
end
end