acts_as_list is another example of poorly documented functionality in Ruby on Rails (I wonder when we can have a good, examples-rich documentation for RoR? php.net's approach will work perfectly). This blog entry will show how to use :scope in case you want to match it against string/varchar columns.I will cite the acts_as_list documentation right here:
acts_as_list(options = {})Configuration options are:
- column - specifies the column name to use for keeping the position integer (default: position)
- scope - restricts what is to be considered a list. Given a symbol, it‘ll attach "_id" (if that hasn‘t been already) and use that as the foreign key restriction. It‘s also possible to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. Example: acts_as_list :scope => ‘todo_list_id = #{todo_list_id} AND completed = 0‘
Well yeah. It tells you that you can customize scope with more than a single parameter. And the example is the simplest one - it uses just integer-based columns for matching. But what is you want to match scope agains a string value? This becomes a little tricky. I remember spending alot of time trying to understand why the bloody code just doesn't work (throwing errors at me).
Here's a little example of how you would use :scope when you want to match against several parameters, with some parameters being string values, and not integers.Say, you have the following structure: a list of pages, each of the page belongs to a category using "category_id" column, and also has a "page_type" determining a page type, which is a string value (ex: 'normal_page', 'inquiry_page', etc..). And say, you want to make these pages into an ordered list, so pages are ordered inside a category. This is simple. You just write:
acts_as_list :scope => :category
there's another possible syntax for the same functionality:
acts_as_list :scope => 'category_id=#{category_id}'
and you're done. But! What if you want pages of different types inside the same category to be ordered individually (or just add the ordering to a subset of pages)? This way you want a double-scoping by category_id and page_type. And page_type being a varchar/string-based column. How to do that kind of scoping? Here's how:
acts_as_list :scope => 'category_id=#{category_id} and page_type=\'#{page_type}\"
Please note that it seems (at least from my tests) that only single-quote characters can be used. No, you can't use double-quote characters inside single-quoted string, and no, you can't do otherwise. You must enclose the :scope definition in single quotes, and use escaped single-quotes when you want to match the scope against char table column.Well, the entry turned out to be about 10x longer than originally planned.. But hopefully it will save you an hour or so trying to figure out how to make the bloody scoping thing work.