Search

Sara Trice

Just a programmin', bellydancin', cake bakin' kinda girl

Women’s Olympic Foil 2012

Congrats to Italy for sweeping Women’s Foil! And congrats to Lee Keifer for making it to 5th – further than any woman from the US has since 1956!

Standings: http://en.wikipedia.org/wiki/Fencing_at_the_2012_Summer_Olympics_%E2%80%93_Women’s_foil

Advertisements

Paperclip, Amazon S3 Storage, the Amazon AWS-SDK gem, and Error: “No such file or directory”

So at work, we switched from using the aws-s3 gem (unofficial) to the aws-sdk gem (official), since the new paperclip gem version required it. Added a new initializer file and made a few changes in how we were opening the S3 connection. No big deal.

Until we got to the part where we were opening a remote URL, reading its contents (an MP3), and trying to save it to a file on S3. (Before you get all riled up about piracy, it’s a voice generator service that we pay for.) So after switching gems, all we got when trying to grab the remote file was:

  No such file or directory - http://www.blahblahblah...

At first I thought it might be the service, but plugging in any other url didn’t work either. Arrgh! The code didn’t change in that respect! WTH?

Yeah well, apparently something did with the gem, because putting:

  require 'open-uri'

at the top of the controller fixed it all up.

Hope this saves you some time/hair pulling/frustration.

Indexing users that belong to groups with ancestry and thinking sphinx

So you’ve created a table of groups that are in a hierarchy with the gem ancestry, and you’ve created a table of users, and you’ve joined users to groups with a join table.

And now you want to use Thinking Sphinx, which is awesome for searching. So you think, hey, wouldn’t it be great if I could do a search for all users in a group’s subtree? Except that Thinking Sphinx cares not for your puny ancestry methods, and :subtree_ids doesn’t work in an index.

Fear not! I’ve done the heavy lifting for you.

in user.rb:
define_index do
  indexes last_name
  has groups(:id), :as => :direct_group_ids
  has "CONCAT_WS('/',groups.id,groups.ancestry)", :as => :group_ids, :type => :multi
end

The first attribute is so that the join is made from users to groups. The second actually creates the multi-value attribute that you can search on. So from there you can do:

User.search(:with_all => {:group_ids => [1]})

That will give you all the users that belong to the subtree, including the root group (in this case, the group with the id of “1”).

That being said, if you only want the users from sub-groups of the group you’re searching on (i.e. you never want users that are directly attached to the group you’re searching on), you can instead do this:

in user.rb:
define_index do
  indexes last_name
  has groups(:ancestry), :as => :group_ids, :type => :multi
end

So if you have group 1 which has group 2 and group 3 as children, the first example will give you all the users attached to all 3 groups; the second example will only give you the users attached to groups 2 and 3.

One last gotcha: if you’re running the search in console, remember to add “:per_page => 100” or however many entries you want back, or else by default you only get 20. Don’t want you to headdesk when you can’t figure out why it’s returning 20 users when it’s supposed to be returning 75.

Happy indexing!

Avoiding Ruby hash conditionals in Ruby on Rails

This gets really old:

if params[:teacher] && params[:teacher][:id] ...

so instead, do this:

if params[:teacher].try(:[], :id)

or do it a lot more:

name = params[:company][:owner][:name] if params[:company] and params[:company][:owner] and params[:company][:owner][:name]

turns into:

name = params.try(:[], :company).try(:[], :owner).try(:[], :name)

Yay for Stack Overflow!

Quickie: How to add a blank option to options_from_collection_for_select

<%= select_tag "some_select", ("<option></option>" + options_from_collection_for_select(@foo, "id", "item")).html_safe %>

Using javan/whenever on Engine Yard Cloud

via Deploy Hook

UPDATE 4.10.2013: Updating these instructions to use bundle exec, per chintan/Nic Pillinger
UPDATE 11.4.2013: Updating these instructions to use helper methods to determine which instances to run the command on

If you want your crontab updated by whenever on deploy, make a file named deploy/before_restart.rb and stick this in it:

on_app_master do
  # the following updates the crontab upon deployment
  run "cd #{config.release_path}; bundle exec whenever --set environment=#{config.framework_env} --update-crontab '#{config.app}_#{config.framework_env}'"
end

This is called a ‘deploy hook’ and here’s more info.

via Deploy Hook using Binstubs

Since Engine Yard automatically installs your binstubs, you could also replace “bundle exec whenever” with “ey_bundler_binstubs/whenever”. If you want to be able to run “bin/whenever” you’ll have to symlink to ey_bundler_binstubs – but remember it’s in the current deploy directory, so you’ll have to do this per-deploy – which means you could stick this in the same before_restart.rb file (obviously it would need to be above the whenever block):

run "ln -nfs #{config.release_path}/ey_bundler_binstubs #{config.release_path}/bin"
on_app_master do
  # the following updates the crontab upon deployment
  run "cd #{config.release_path}; bin/whenever --set environment=#{config.framework_env} --update-crontab '#{config.app}_#{config.framework_env}'"
end

Note for Utility Instances

UPDATE 11.4.2013: If you also want your cron jobs to work on all app servers (not just your app master), change “on_app_master” above to “on_app_servers”. For app servers and utilities, use “on_app_servers_and_utilities”. For utilities only, use “on_utilities”. As far as I can tell, there does not appear to be an option for only app master and utilities; if you need this, write two identical blocks with “on_app_master” and “on_utilities”.

via Custom Chef Recipes

Why would you also need to do a custom chef recipe? Because if you rebuild your cluster and don’t redeploy, your cron jobs won’t be created.

UPDATE 4.17.2012: If you’re on EY and not using custom chef recipes, you should start. A whenever recipe has been written and is detailed here. Info on how to start using custom chef recipes is here. It’s not so bad, really. One gotcha: your “appname” in the recipe is not your rails application name, but your EY application name – these can be different things!

Illinois Home Bakeries – for farmer’s markets only

Interesting tidbit about a new law that is being passed. IL Senate Bill 840 allows for “Cottage food operations” (i.e. you can use your home kitchen), with several stipulations, if and only if you are selling goods at a farmers’ market. So if I wanted to sell my cakes at a farmer’s market and got the appropriate paperwork, I could, but I still couldn’t sell them to individuals specifically out of my home. I’d have to have a table at a farmer’s market. Which is pretty much useless to me. Oh well, it’s a step in the right direction.

Article from the News-Gazette
Article from the IL Stewardship Alliance
Senate bill 840

jsTree: adding Expand All and Collapse All buttons

The documentation for jsTree is thorough, but not particularly easy to read. If you are looking for an easy way to add “Expand All” and “Collapse All” buttons, here’s one way:

<input type="button" value="Collapse All" onclick="$('#tree_container_id').jstree('close_all');">
<input type="button" value="Expand All" onclick="$('#tree_container_id').jstree('open_all');">

where ‘#tree_container_id’ is, of course, the ID of the container node for your tree.

Uploadify: changing scriptData with dropdowns

Uploadify is a pretty awesome jQuery/flash uploader. It’s made even more awesome by the stuff you can do with it on the fly.

For example, if you want to pass a variable chosen from a dropdown via the uploader, you can use uploadifySettings() to do so. Some people appear to have problems with this part, so here’s how I did it. (I’m not going to show you all the settings, since the docs give you a pretty good idea how to set it up. )

Say you have a dropdown in your form with the id of ‘upload_type’:

<select id="upload_type" name="upload_type">
<option></option>
<option value="1">First type</option>
<option value="2">Second type</option>
</select>

In your jQuery $(document).ready function (but outside the $(‘#upload’).uploadify function), put something like this:

$('#upload_type').change(function() {
var type_val = $(this).val();
$('#upload').uploadifySettings("scriptData", {"upload_type" : type_val});
});

Which means “Whenever the form field identified with ‘upload_type’ changes, update the ‘upload_type’ variable in scriptData if it exists; if it does not already exist in scriptData, add it.”

Note: I’ve only tried this in Uploadify 2.1.4.

Create a free website or blog at WordPress.com.

Up ↑