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.

The Class#inherited method in Ruby

For the impatient:

[Class#inherited is a] Callback invoked whenever a subclass of the current class is created – ApiDock


The long story: Today I stumbled over a piece of code like the following:

class Foo
  class << self
    def inherited(subclass)
      $subclasses << subclass
    end
  end
end

The interesting thing is that this was the only occurrence of inherited in the entire codebase, so I instantly assumed some Ruby magic and went over to RubyDoc, but didn’t find anything there. After some additional Googling I found a mailing list post which confirmed that inherited is a method on Class, but it still didn’t explain why it didn’t show up on RubyDoc.

It turned out that apparently RubyDoc only shows public methods, which IMO is pretty confusing (at least it was for me). I finally found my missing method on ApiDock, which does show private methods.

Renaming Typo3 plugins created by the “kickstarter” extension

Unfortunately it is not possible to give meaningful names to the plugins created by the kickstarter extension, so they’re all named pi1, pi2 and so on. Because this can get rather tiresome if you’ve got multiple plugins inside the same extensions, I’ve written a small ruby script to rename them.

Continue reading

Ruby: attr_accessor for Class Variables

Here’s how you do it:

class Foo
    class << self
    # Everything here is in class scope
        attr_accessor :bar
    end
end

That’s it. What class << self does is, it puts you in a class definition block for the singleton Class instance of Foo. Lets make that a bit clearer with an example. The following two snippets are functionally identical:

class Foo
    def self.bar
        42
    end
end

is the same as

class Foo
    class << self
        def bar
            42
        end
    end
end

Sometimes I wonder why other languages aren’t as elegant as Ruby. But then again, it’s somewhat difficult to get your head wrapped around some of the meta-programming concepts of Ruby, too.

Thanks to these guys for the solution.

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.