17

Is there something like:

respond_to do |format|

  format.html || format.xml do
    #big chunk of code
  end

end

I would like to do that for DRY's sake.

hello_there_andy
  • 2,039
  • 2
  • 21
  • 51
miligraf
  • 1,042
  • 9
  • 22
  • so what format do you want the block to return - html or xml? You can put all the logic outside of the respond_to and then only format it html/xml at the end - does that help? – John Beynon Aug 23 '11 at 05:47
  • See http://stackoverflow.com/a/2430682/265940 for a better answer using format.any(:html, :xml) {...} – Gerry Shaw Nov 20 '12 at 23:04

3 Answers3

47

Respond_to actually allows you to specify your common block for different formats by using any:

format.any(:js, :json) { #your_block }
Tom Chinery
  • 611
  • 6
  • 2
  • 1
    Actually I think this is the only real useful answer. I couldn't get the "Proc" answer running _and_ this one is definitively shorter and cleaner. Tks! – fenton Oct 08 '13 at 16:30
  • Also, `format.all` is a synonym for `format.any` if that makes more sense to you. – Erik Sandberg Jul 08 '14 at 09:57
4

You can use a format like this:

class PeopleController < ApplicationController
  respond_to :html, :xml, :js

  def index
    @people = Person.find(:all)
    respond_with(@people) do |format|
        format.html
        format.xml
        format.js { @people.custom_code_here }
    end
  end
end

Which would achieve what you are looking for, if you have a situation that is more complex let me know. See this article on the respond_with method for more help.

Devin M
  • 9,636
  • 2
  • 33
  • 46
  • Forgive me for answering until now, the thing is that: I want to format.html and format.xml share the same bunch of code but I also have format.js which I don't want it to have access to format.html's or format.xml's code (which in this case it would be the same). – miligraf Sep 21 '11 at 21:02
  • Use the modified version of the code above. If you have any questions let me know. – Devin M Sep 22 '11 at 04:49
1

when you

respond_to do |format|
  format.html do
    #block
  end
  format.xml do
    #block
  end
end

or you

respond_to do |format|
  format.html { #block }
  format.xml { #block }
end

you are taking advantage of ruby blocks, which are evaluated as Procs. Therefore you could do

respond_to do |format|
  bcoc = Proc.new do
    # your big chunk of code here
  end
  format.html bcoc
  format.xml bcoc
end

but perhaps you could move some of that logic into your data structure?

Alec Wenzowski
  • 3,878
  • 3
  • 25
  • 40
  • Ty Alex, I will go with this solution as I can restrict format.js access to format.html/xml's code. – miligraf Sep 21 '11 at 21:03
  • Ruby blocks aren't Procs. They can be converted back and forth, but they're not the same thing. – Matthew Ratzloff Sep 16 '12 at 20:32
  • @MatthewRatzloff My understanding is that block syntax is exactly that: the most common ruby syntax for defining a closure. See [https://gist.github.com/3757938](https://gist.github.com/3757938). What are they then? Happy to be corrected. – Alec Wenzowski Sep 20 '12 at 19:48
  • @AlexanderWenzowski There's a lot of misinformation out there. The ampersand unary operator converts a block to a Proc, which is why it reports itself as a Proc. Blocks are distinct from Procs, but can be easily converted back and forth. Procs are actually created from blocks; blocks are simply a lighter-weight construct. The differences are minor but they have different names for a reason. :-) (Also see http://www.loudthinking.org/2009/10/block-vs-lambda-vs-proc.html and http://www.ruby-doc.org/core-1.9.3/Proc.html) – Matthew Ratzloff Sep 20 '12 at 21:01