responder_controller
Rails 3 responders wrap up as much crud controller code as possible without finding or mutating models on your behalf. This is a sensible cut-off for framework support, but it still leaves a fair amount of duplicate code in crud controllers. App developers are free to abstract more.
This is me abstracting more for my own apps. If it’s handy for you, go nuts.
Example
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
scope :authored_by, lambda { |user_id| where(:user_id => user_id) }
scope :recent, lambda { |num| order("updated_at DESC").limit(num.to_i) }
end
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
include ResponderController
respond_to :html, :xml, :json
# restrict to just the current user's posts
scope { |posts| posts.authored_by current_user.id }
end
# Client-side
GET /posts.html # renders Post.authored_by(your_id)
GET /posts.html?recent=10 # renders Post.authored_by(your_id).recent(10)
GET /posts/1.html # renders post 1 if you authored it, or 404
PUT /posts/1.html # update same
DELETE /posts/1.html # or delete it
Point it at a different model class:
class ProfilesController < ApplicationController
include ResponderController
serves_model :user
end
Forbid a certain scope
class PostsController < ApplicationController
include ResponderController
serves_scopes :except => :authored_by # asking for it will 403
end
Or use a white list instead
class PostsController < ApplicationController
include ResponderController
serves_scopes :only => :recent
end
Serve resources in a namespace:
class PostsController < ApplicationController
include ResponderController
responds_within 'my-blog'
end
# Client-side
GET /my-blog/posts.html
A nested resource, using blocks for dynamic behavior:
class CommentsController < ApplicationController
include ResponderController
# Only get comments for the identified post
scope do |comments|
comments.where :post_id => params[:post_id]
end
# Nest the comments under the post
responds_within do |comments|
Post.find(params[:post_id])
end
end
The same:
class CommentsController < ApplicationController
include ResponderController
children_of :post
end
Note on Patches/Pull Requests
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Thanks
Thanks to SEOmoz (seomoz.org) for letting me build this at my desk in the afternoons instead of on the couch in the middle of the night ^_^.
Copyright
Copyright © 2010 Phil Smith. See LICENSE for details.