Whenever Gem and Capistrano – Specifying the cronjob user

If you are using Capistrano in a project that relies on the Whenever gem to manage your crontab, it will update the crontab of the user that you use for your Capistrano deploys. So if, for example, you’d deploy with the user capistrano and your app runs under the user www-data, you could run into all sorts of trouble, e.g. permissions in case your cronjob creates new files.

Specifying the user under whom the cronjob command should be executed is relatively easy though. This mailing list entry tells us that we should add --user your_user as a parameter to the whenever command. The problem with that is that you don’t execute the command yourself, but the whenever gem’s Capistrano recipe does. So all we need to do is change the whenever_update_flags variable to meet our wishes. First the original line, and after that our modification:

# Old
_cset(:whenever_update_flags) { "–update-crontab #{fetch :whenever_identifier} –set #{fetch :whenever_variables}" }

# New
_cset(:whenever_update_flags) { "–update-crontab #{fetch :whenever_identifier} –set #{fetch :whenever_variables} –user www-data" }

You probably don’t want to change the whenever gem directly, so placing that line anywhere in the deploy.rb file should work just fine.

Rails 3 Routing Parameters with Dots

By default, Rails 3 interprets a dot in a URL as a format specifier. For example, given the route

match "/foo/:search"

and the URL /foo/bar.baz, this would result in the following parameters being passed:

{ :search => "bar", :format => "baz" }

This may not be what you desire, so here is a quick workaround, using segment constraints:

match "/foo/:search", :constraints => { :search => /[^\/]*/ }

The constraint for the :search parameter now matches anything but a slash, which includes the dot, and Rails will no longer interpret it as a format.

Update: The same effect can be achieved by using dynamic segments and the same regular expression, like this:

match "/foo/:search", :search => /[^\/]*/

 

Update2: If you want to also ignore slashes within the URL, you can do the following:

match "/foo/:search", :search => /.*/

With this matcher, if you’d open the URL “/foo/los.tacos/son.deliciosos” it would result in a search parameter with the value “los.tacos/son.deliciosos“.


Thanks to this guy and this guy, who led me in the right direction.

This is a small update on a blog post which I wrote back on my old blog. Still need to find a way to move all those articles over to this blog without breaking the links.