Twisting words! (boustrophedon formatting)
Looks fine to me. Only thing I'd change is the way the padding is done: You can use ljust instead, which seems a little more appropriate to me. Something like:

.ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ")


You can also use the with_index modifier on map instead of doing a separate each_with_index, i.e.:

.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }




Of course there are several approaches to this. For instance, you needn't necessarily use chars and then join. For instance:

def twist(text, chunk_size)
  text
    .ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ")
    .scan(%r/.{#{chunk_size}}/)
    .map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
    .join("\n")
end


I won't say it's a better solution, though. Fewer lines, sure, but the interpolated regex isn't pretty. But again, it's just to show an alternative approach.

You can also move the ljust, to avoid the long'ish bit of arithmetic:

def twist(text, chunk_size)
  text
    .scan(%r/.{1,#{chunk_size}}/)
    .map { |chunk| chunk.ljust(chunk_size, " ") }
    .map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
    .join("\n")
end


It's obviously it's kinda brute-force, since we know that it'd only be the last chunk that could require padding. But again: Just an alternative.