strapyourself.in and flouri.sh
Duplicate joins merge in rails 2.2
If you've ever suffered from duplicate table aliasing problems in rails, there's a new feature in 2.2 that will help some of these situations go away. This seems to come up mostly in named_scope, where you want to define a list of scopes that can work by themselves or with any other scopes. This often means having identical or similar joins in multiple scopes. Take this example:
class User has_one :profile named_scope :male, { :join => "INNER JOIN profiles ON profiles.user_id = users.id", :conditions => "profiles.gender = 'male'" } named_scope :recently_updated, { :join => "INNER JOIN profiles ON profiles.user_id = users.id", :conditions => ["profiles.updated_at > ?", 1.week.ago] } named_scope :admin, { :join => "INNER JOIN profiles ON profiles.user_id = users.id AND profiles.admin = 1 INNER JOIN emails ON emails.profile_id = profiles.id" } named_scope :with_profiles, { :join => :profile } end
Before 2.2, calling User.male.recently_updated results in a table aliasing problem, because rails joins
in the profiles table twice. Three features in 2.2 make this better:
- :join with hash/symbol syntax merges hashes when combining scope (Andrew White)
- :join now can take an array of strings (David Stevenson & Joseph Palermo)
- string identical joins are uniqued when combining scopes (David Stevenson & Joseph Palermo).
After 2.2, you can call User.male.recently_updated because there are two string identical
joins combined in different scopes. You can't call User.male.admin without making some
modifications, because the two joins involved are not string identical. Here's how I'd modify the
:admin scope:
named_scope :admin, { :join => ["INNER JOIN profiles ON profiles.user_id = users.id", "INNER JOIN emails ON emails.profile_id = profiles.id"], :conditions => "profiles.admin = 1" }
By using the array of strings :join syntax, I can let rails know that those are two separate joins,
each of which can be merged if an identical join comes up in another scope. I also moved the extra join
condition (profiles.admin = 1)to :conditions, so that the INNER JOIN statement would not have any specific logic for that
particular named_scope in it.
I still can't call User.male.with_profiles because the string representation of the join
from with_profiles probably doesn't match the join from male. It will be off
due to the way rails generates join using different whitespace and escape characters than I originally
wrote. This can be easily fixed by copying the exact string rails generates from
:join => :profileand pasting it into male.
acts_as_solr has a new home
Developers finally set up master repo for acts_as_solr
After a long time of no development, a new acts_as_solr plugin has emerged on GitHub. Luke Francl & Mathias Meyer have adding a lot to the old plugin and created a new "master". Mathias has merged several branches on github including changes from David Palm, kengruven, and myself. This is great news for people running/modifying acts_as_solr, as Mathias is a real person who will actually respond to your pull requests. Some new features include:
- SOLR 1.3 installed
- Ruby 1.9 support
- LibXML 0.7+ support
- Store types as
stringnottextfields in the index - JVM options in solr.yml
- Completely rewritten test suite
- New solr:reindex task that automatically finds and indexes your solr models