Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You might want to have a look at <a href="https://github.com/josevalim/inherited_resources" rel="nofollow">inherited_resources</a>. It can be used to dry up your controllers and for simple case (like yours apparently) can reduce your manual controller to just a couple of lines.</p> <p>If your controllers are are still too similar then, you could also apply some meta-programming and create the controller classes on the fly in some initializer like this</p> <pre><code>%w[Foo Bar Baz].each do |name| klazz = Class.new(ApplicationController) do respond_to :html, :json def index @model = name.constantize.find(params[:id]) respond_with @model end end Kernel.const_set("#{name}Controller", klazz) end </code></pre> <p>This code will create three minimal controllers called <code>FooController</code>, <code>BarController</code>, and <code>BazController</code>.</p> <p>If you are just calling <code>model.to_json</code> in your views, you don't need views at all. Just use <code>respond_to</code> and <code>respond_with</code> (inherited_resources and my example code above do that). See <a href="http://www.edgerails.info/articles/what-s-new-in-edge-rails/2009/08/06/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with/index.html" rel="nofollow">one of the many articles</a> about its usage for more information.</p> <hr> <p>Edit: The meta-programming approach would help you avoid the copy&amp;paste of many identical controllers. You still should put as much code as you can in a common parent class (or some included modules). In the end, maintaining a couple of almost empty classes isn't <em>that</em> bas as you don't copy complex code.</p> <p>The example above could also expressed with less meta-programming but exactly the same behavior like the following example. This approach is probably a bit more natural. It still gives you almost all the advantages of the full-meta approach.</p> <pre><code>class MetaController &lt; ApplicationController respond_to :html, :json def index(&amp;block) @model = model.find(params[:id]) instance_eval(&amp;block) if block_given? # allow extensions respond_with @model end protected def model @model_class ||= self.class.name.sub(/Controller$/, '').constantize end end class FooController &lt; MetaController end class BarController &lt; MetaController def index super do @bar = Specialties.find_all_the_things end end end class BazController &lt; MetaController end </code></pre> <p>As another point of thought, I included a simple extension mechanism. In child classes, you can pass a block to the <code>super</code> call to perform additional steps which might be required by a slightly special view.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload