Default Scopes and Hash Posers
Posted on September 07, 2009
While I was editing my last article I was thinking about multi-site. Usually, Railers prefer to have a single app per Rails project. But what if I do want to have a CMS, an e-Commerce, something like Wordpress MU and so on?
I thought to myself: “dead simple: just add default_scope to the relevant Active Record models”. Ended up not being quite so simple because it seems like ’defaultscope’ doesn’t support blocks just yet as you can follow on this open ticket at Lighthousescope-cant-take-procs.
The problem is that ‘default_scope’ will be different per user, so I can’t have an static conditions hash pre-defined in the model. To solve that – at least until a more official solution comes along – Brian Mitchell has a great suggestion: use a Hash Poser.
Now, a Hash Poser is a class that acts and behaves exactly like a normal Hash. Let’s see his code:
Dead Simple, you can copy and paste this code to somewhere like ‘config/initializers/hash_poser.rb’. You can easily see how this can be used in your models:
1 2 3 4 5 |
class Post < ActiveRecord::Base default_scope HashPoser.new do { :conditions => { :user_id => UserSession.find } } end end |
This is supposing you’re using something like Authlogic, but actually you will want something more like ‘Site.find’ or whatever. The point is, now whatever finder you were using throughout your application will have this conditions added to it. So, a simple ‘Post.all’, in this example, will automagically run:
1 |
SELECT * FROM "users" WHERE ("users"."id" = 1)
|
Considering that you’re not using something like ‘find_by_sql’ with hand crafted SQL queries, the ‘default_scope’ will override all your finders. Of course, it’s easier said than done, so have your test suite ready when you do this change. As I said, you will have to add a column like ‘site_id’ to every table you need to be multi-site.
I would like to see what other people think of this way of thinking and what caveats there are for this use case. Most of the time Rails apps will be stand-alone, but in a few exception cases, we really do want to have a single app serving multiple customers. What’s your take on this concept?
blog comments powered by Disqus
Archives
- February 12(2)
- December 11(1)
- November 11(4)
- October 11(6)
- September 11(5)
- August 11(1)
- July 11(5)
- May 11(4)
- April 11(11)
- March 11(4)
- February 11(3)
- January 11(4)
- December 10(9)
- November 10(2)
- October 10(10)
- September 10(4)
- August 10(6)
- July 10(14)
- June 10(16)
- May 10(8)
- April 10(14)
- March 10(9)
- February 10(6)
- January 10(14)
- December 09(10)
- November 09(10)
- October 09(7)
- September 09(19)
- August 09(4)
- July 09(12)
- June 09(7)
- May 09(12)
- April 09(11)
- March 09(9)
- February 09(9)
- January 09(12)
- December 08(14)
- November 08(20)
- October 08(15)
- September 08(18)
- August 08(25)
- July 08(13)
- June 08(21)
- May 08(29)
- April 08(27)
- March 08(12)
- February 08(32)
- January 08(31)
- December 07(27)
- November 07(30)
- October 07(25)
- September 07(28)
- August 07(16)
- July 07(15)
- June 07(16)
- May 07(7)
- April 07(13)
- March 07(8)
- February 07(9)
- January 07(24)
- December 06(17)
- November 06(17)
- October 06(15)
- September 06(38)





