Since then, I've been hacking away on features that were sorely missing. Today, I've got a handful of those to release.
The star of Friendly 0.4.0 is scopes. Here's how they work.
Assuming the following model:
class Post attribute :author, String indexes :author, :created_at end
To create a scope on the fly, just call YourDocument.scope.
@scope = Post.scope(:author => "Stewie Griffin")
You'll get back an instance of Friendly::Scope. That object supports almost all of the query and creation API that a Document class does.
@scope.all == Post.all(:author => "Stewie Griffin") @scope.first == Post.first(:author => "Stewie Griffin") # these won't actually evaluate to true, but I mean to say that the syntaxes are identical @scope.build == Post.new(:author => "Stewie Griffin") @scope.create == Post.create(:author => "Stewie Griffin")
It's also possible to create reusable, named scopes.
The named scope syntax is pretty well identical to ActiveRecord's:
class Post # ... snip ... named_scope :by_stewie, :name => "Stewie Griffin"
Then, you can get an instance of that scope with:
A named scope instance is just another instance of Friendly::Scope. Unlike with ActiveRecord, you must call scope.all to get the target of the scope. You can also use any of the other scope methods:
Post.by_stewie.all == Post.all(:name => "Stewie Griffin") Post.by_stewie.create.name == "Stewie Griffin" # ... and so on
Named scopes are also chainable arbitrarily.
class Post # ... snip ... named_scope :recent, :order! => :created_at.desc end Post.by_stewie.recent == Post.all(:name => "Stewie Griffin", :order! => :created_at.desc)
If there are conflicts, the right-most scope takes precedence.
class Post # ... snip ... named_scope :by_peter, :name => "Peter Griffin" end Post.by_stewie.by_peter == Post.all(:name => "Peter Griffin")
Currently, only has_many associations are supported.
class User has_many :posts end class Post # ... snip ... attribute :user_id, Friendly::UUID indexes :user_id, :created_at end
The cool thing is that associations are just another instance of Friendly::Scope.
User.new.posts # => #<Friendly::Scope>
So, all of the Friendly::Scope methods are supported. You can also chain named_scopes on an association.
@user = User.create @user.posts.recent == Post.all(:user_id => @user.id, :order! => :created_at.desc)
Jeff Rafter contributed a few awesome patches.
Most notably, Friendly was previously unable to create an index table for a field of type Friendly::UUID. Jeff added support for mapping custom types to database field types.
There are no docs yet, but the method signature for Friendly::Attribute.register_type should be clear enough. For most purposes, though, the big win is that Friendly should now be able to create tables for you more consistently.
Jeff also added a spec/config.yml for putting your spec db settings in.
Get it while it's hot!
sudo gem install friendly
- Watch the github project.
- Join us in irc at #friendlyorm on freenode.