-
Iterate over a collection in groups, and other things
One thing I find fascinating about Ruby is the fact that most common tasks are already programmed for you in its library. The Enumerable module is a clear example of that, providing you with lots of functionality to manipulate collections of objects.
One of those useful methods I discovered the other day was each_slice. This method allows you to iterate over the collection, just as each does, but lets you do it changing how many elements of the collection you get on each iteration. This is the example you can get from the documentation page:
(1..10).each_slice(3) {|a| p a} # outputs below [1, 2, 3] [4, 5, 6] [7, 8, 9] [10]
You can see that from the original array from 1 to 10, on every iteration Ruby prints the numbers in groups of three, and the last one alone since the collection is not a multiple of 3. Now think about having to do this manually: it's not that hard, but its error prone and you have to do all that typical arithmetic logic that should be easy but never is. How handy that Ruby has already done that job for you.
This method is also pretty useful when working in Ruby on Rails. One simple example is when you have to manually implement some kind of pagination, or show a list of elements in columns or rows of fixed size: you have to simply iterate with each_slice and put the page/row/column logic on the block, and voilà.
I strongly suggest you take a look at the Enumerable module reference to take a look at all the other flavours of each methods it has and I'm sure you'll find all of them pretty useful in lots of situations!
-
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!