• Easily select random records in rails

    If you ever wondered how to easily retrieve a random record in an ActiveRecord model, here’s en easy way to do that: use the sample method.

    sample is a class method from the Array class that retrieves one or more random items from an array instance. It conveniently returns nil or an array lesser than the items requested if the original array has not enough items.

    Since all ActiveRecord finds return an array, you can easily add the sample call at the end of a find call to get the random items you need from complex queries.

    For example, imagine you have a Book model which has a published_at datetime attribute and you want to show, in your library home page, a random selection of 5 books that have been published. You can easily get those using this snippet:

    def get_random_books_for_home_page
      find(:all).sample(5)
    end

    EDIT (30/11/2012): after revisiting this post I obviously found out that this is in fact a very inefficient way to get random records for large collections, as Rails will have to instantiate them all, then performing a random on them. Unfortunately, seems like the only way to get a true random collection of items is to perform the sort on the database engine and then getting the first n elements of the resulting query, which will also be slow for large collections. This can be done like this:

    def get_random_books_for_home_page
      Books.order("RAND()").first(5)
    end

    In this case we tell mySQL to sort the collection using the internal RAND() method. One problem with this solution is that it’s database-engine specific (the sorting method may be named different in other engines, and in fact at least in PostgreSQL is). Other solutions try to get pseudo random records using the id column, for example by getting the n first records which id is greater or lower than a certain number. While this may be ok in most cases (considering you use a random index to compare with based on the min and max for id values) it may not be so good in other cases.

  • WordPress AddToAny plugin

    If you encounter problems after upgrading Wordpress and the AddToAny plugin version .9.9.9.1 (the one I tested), try to update your footer.php file of your current theme too add this line just before the closing body tag:

    <?php wp_footer(); ?>

    It seems that newer versions of the plugin put some javascript code into the footer section, so without this call, there's no javascript for AddToAny, and without javascript, you can't see the popup div that allows you to select the service you want to use to share your posts.

  • Fixtures and serialized attributes in Ruby on Rails

    If you've ever used the serialize method in an ActiveRecord model, you may have faced the problem of writing a fixture for that particular serialized field. The serialize method is quite handy if you need to store a complex object (like a Hash or an Array) in a database field, without having to create additional models and relationships between them. A good example could be store the preferences of a user in a hash:

    class User < ActiveRecord::Base
        serialize :preferences, Hash
      end

    This way you can set and get the preferences attribute of the user without having to worry much about it:

    User.first.preferences # => {:show_email => true, :allow_pm => :false, ...}
    user = User.first
    user.preferences = {:show_email => true, :allow_pm => :false}
    user.save

    In order to do that, at the database table for the User class, among the other fields you'll need to add a text column for the preferences. After that, you can easily work with your model without too much of a hassle.

    If you care to look at the rows of the model's table, you'll see that the serialized attribute is stored in YAML format:

    sqlite> select preferences from users where id = 1;
    --- 
    :show_email: false
    :allow_pm: false

    Now, that if you need to add a fixture for your model that needs the preferences attribute to be set to a particular value? If you have to manually parse the value you want to put in there to be tested, it'll be a pain in the ass. Even if you have a script that converts certain values to YAML so you can copy and paste the script output to the fixture, it's not very comfortable. Hopefully, you have to remember that you can use some ERB magic in your fixtures :) So, here's the deal if you need to add something to the serializable attribute:

    one:
      preferences: <%= {:show_email => true, :allow_pm => :false}.to_yaml.inspect  %>

    The to_yaml method converts the Hash into a YAML representation, and with inspect we convert that to a string. Using this technique, we can add whatever we want to a serialized field in our fixtures.

  • Installing xmonad in ArchLinux

    For some reason, the ArchLinux wiki is kind of outdated explaining how to install xmonad in Arch. Also, the new packages seem to have a bug and the xmonad installation won't work out of the box. Here you have detailed steps on how to install and run xmonad on ArchLinux. First of all, you need to install the Xorg server. Refer to Xorg for detailed instructions. After that, you'll need to install the xmonad packages, named xmonad and xmonad-contrib.

    pacman -Syu xmonad xmonad-contrib

    This will install xmonad and all the required dependencies. After that, if you want a fairly simple X setup, add the line xmonad to your ~/.xinitrc file (hopefully you'll be using a display manager that uses that file like SLiM). If you try this on a freshly installed ArchLinux system, though, it won't work. There are some missing steps to do. First of all, you need to create the folder ~/.xmonad.

    mkdir ~/.xmonad

    After that, you need to create a new xmonad config file, called xmonad.hs</em into that folder, so fire up your favourite editor and fill the file with this basic (empty) configuration: </p>

    import XMonad
    
    main = do
        xmonad $ defaultConfig

    Once you have you configuration file in place, it's time to rebuild xmonad:

    xmonad --recompile

    And that's all, you should be able to start your fresh new xmonad setup in ArchLinux. By the way, if you wonder why pressing Mod1 + Shift + Enter does nothing, make sure you have the package xterm installed.

    Cheers!

  • Handling resizing in Adobe Air with HTML

    If you develop a widget with Adobe AIR using HTML and Javascript, you may want to resize some elements of the HTML page depending on the size of the widget, thus having to resize them when the user decides to resize the widget. However, there's a little trick on using the RESIZE event of the air.Event object.

    The trick is that when the event is raised, and you execute some method on the corresponding event handler, the widget won't have the correct size yet, so if you use the window.nativeWindow.width or window.nativeWindow.height values there you'll be getting erroneus results.

    The solution is quite easy, though. You just have to let the HTML engine to adjust everything he needs to sort out the new sizes and get those attributes after that. How do you do that? By putting your code in a setTimeout call with 0 milliseconds timer. Here you can find an example (assuming use of jQuery):

    $(document).ready(function() {
        window.nativeWindow.addEventListener(air.Event.RESIZE, onResize);
    });
    
    function onResize() {
        var nativeWin = window.nativeWindow;
        setTimeout(function(){
        var width = nativeWin.width;
        var height = nativeWin.height;
        }, 0);
    } //Here the values are correct