{"id":127,"date":"2009-08-28T11:08:57","date_gmt":"2009-08-28T14:08:57","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=127"},"modified":"2009-08-31T15:53:51","modified_gmt":"2009-08-31T18:53:51","slug":"inherited-resources-is-scopes-and-responder-fluent","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2009\/08\/inherited-resources-is-scopes-and-responder-fluent\/","title":{"rendered":"Inherited Resources is scopes and responder fluent"},"content":{"rendered":"

First, what is Inherited Resources?<\/h3>\n

Inherited Resources<\/a> is a gem\/plugin that allows you to speed up development by making your controllers inherit all restful actions so you just have to focus on what is important. A Rails scaffold controller which responds to html, xml and json is as simple as:<\/p>\n

\r\nclass ProjectsController < InheritedResources::Base\r\n  respond_to :html, :xml, :json\r\nend\r\n<\/pre>\n

However all actions are still customizable! For example, you can change the behavior of the create action on success just doing:<\/p>\n

\r\nclass ProjectsController < InheritedResouces::Base\r\n  respond_to :html, :xml, :json\r\n\r\n  def create\r\n    create! do |success, failure|\r\n      success.html { redirect_to edit_project_url(@project) }\r\n    end\r\n  end\r\nend\r\n<\/pre>\n

It also supports I18n (all flash messages are set with I18n), belongs to association (like a task belongs to project), nested belongs to (task belongs to project which belongs to company), polymorphic belongs to (comments belong to task or file or message) and optional belongs to (the same as previously, but you can request the resource with or without parents).<\/p>\n

As you noticed, besides simplifying your controllers, InheritedResouces makes easy to reproduce your models behavior and relationship in controllers. And right now, it's also scopes and responder fluent!<\/p>\n

has_scope: named_scope twin brother<\/h3>\n

Let's suppose that we have a ProjectsController and at some point you want to add some filters on the index action like showing just featured projects, selecting projects by methodology or even let the user choose how many projects he can see per page. The first thing to do? Add named scopes to your model:<\/p>\n

\r\nclass Project < ActiveRecord::Base\r\n  named_scope :featured, :conditions => { :featured => true }\r\n  named_scope :by_methodology, proc {|methodology| { :conditions => { :methodology => methodology } } }\r\n  named_scope :limit, proc{|limit| :limit => limit.to_i }\r\nend\r\n<\/pre>\n

The next step would be to add a lot of code in your controllers that check which named scopes you should call, based on the parameters sent right? Well, not anymore. Your controller can be as simple as:<\/p>\n

\r\nclass ProjectsController < InheritedResources::Base\r\n  has_scope :featured, :boolean => true\r\n  has_scope :by_methodology\r\n  has_scope :limit, :default => 10, :only => :index\r\nend\r\n<\/pre>\n

Then for each request:<\/p>\n

\r\n\/projects\r\n#=> acts like a normal request, but returning only 10 projects\r\n\r\n\/projects?featured=true\r\n#=> calls the featured named scope and bring 10 featured projects\r\n\r\n\/projects?featured=true&by_methodology=agile&limit=20\r\n#=> brings 20 featured projects with methodology agile\r\n<\/pre>\n

If you configure your routes, you could even have pretty urls with it:<\/p>\n

\r\n\/projects\/agile\/featured\r\n#=> brings 10 featured projects with methodology agile\r\n<\/pre>\n

Yay!<\/p>\n

Responder<\/h3>\n

A couple weeks ago, we wrote about ActionController::Responder<\/a>. But you don't have to wait Rails 3 to be released to play with it, you can start now by using Inherited Resources.<\/p>\n

Quick redirect<\/h3>\n

After using Inherited Resouces, I realized that most of the times I overwrite a create, update or destroy actions is to change the redirect destination. In our ProjectsController above, if we want to redirect to the edit page after create, we would have to do:<\/p>\n

\r\nclass ProjectsController < InheritedResouces::Base\r\n  respond_to :html, :xml, :json\r\n\r\n  def create\r\n    create! do |success, failure|\r\n      success.html { redirect_to edit_project_url(@project) }\r\n    end\r\n  end\r\nend\r\n<\/pre>\n

It wouldn't be cool if it have a shortcut? Now it has:<\/p>\n

\r\nclass ProjectsController < InheritedResouces::Base\r\n  respond_to :html, :xml, :json\r\n\r\n  def create\r\n    create! { edit_project_url(@project) }\r\n  end\r\nend\r\n<\/pre>\n

That simple, just give the url as a proc and since the proc does not expect any parameters, it assumes that you want to overwrite the redirect url.<\/p>\n

Finally some DSL?<\/h3>\n

Last weeks, there was a discussion on Boston.rb group<\/a> about different resource controllers gems. Reading some of the feedback there, I've decided to stab a DSL to Inherited Resources. It will mainly remove the duplication when you have to give a block, the previous example above could be written as:<\/p>\n

\r\nclass ProjectsController < InheritedResouces::Base\r\n  respond_to :html, :xml, :json\r\n\r\n  create! do |success, failure|\r\n    success.html { redirect_to edit_project_url(@project) }\r\n  end\r\nend\r\n<\/pre>\n

Or even in the compact form:<\/p>\n

\r\nclass ProjectsController < InheritedResouces::Base\r\n  respond_to :html, :xml, :json\r\n  create! { redirect_to edit_project_url(@project) }\r\nend\r\n<\/pre>\n

Those changes were not applied yet, it depends mainly on you. If you like or not, let us know in the comments!<\/p>\n","protected":false},"excerpt":{"rendered":"

First, what is Inherited Resources? Inherited Resources is a gem\/plugin that allows you to speed up development by making your controllers inherit all restful actions so you just have to focus on what is important. A Rails scaffold controller which responds to html, xml and json is as simple as: class ProjectsController < InheritedResources::Base respond_to ... \u00bb<\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[24,23,7],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/127"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=127"}],"version-history":[{"count":12,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/127\/revisions"}],"predecessor-version":[{"id":157,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/127\/revisions\/157"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}