Multicolumn iterations with cucumber data tables in Ruby Cucumber is not designed to support multi-column iterations, but it is possible to make it work. Here, I want to try each combination of path and role.

This is the Cucumber Gherkin:

  Scenario: cannot access paths
    When I access "path" as "role" then I should see an error
      | /path1 | user1 |
      | /path2 | user2 |
      | /path3 | user3 |
      | /path4 |       |


And this is the Cucumber step_definition:

When(/^I access "path" as "role" then I should see an error$/) do |table|
  paths, roles = table.raw.transpose.map { |e| e.reject(&amp;:blank?) }
  roles.each do |role|
    step "I am logged in as #{role}"
    paths.each do |path|
      p "#{role} user visiting #{path}"
      visit path
      step 'I should see the privileges error'
    end
  end
end


table.raw looks like:

[
    [0] [
        [0] "/path1",
        [1] "user1"
    ],
    [1] [
        [0] "/path2",
        [1] "user2"
    ],
    [2] [
        [0] "/path3",
        [1] "user3"
    ],
    [3] [
        [0] "/path4",
        [1] ""
    ]
]


and table.raw.transpose produces:

[
    [0] [
        [0] "/path1",
        [1] "/path2",
        [2] "/path3",
        [3] "/path4"
    ],
    [1] [
        [0] "user1",
        [1] "user2",
        [2] "user3",
        [3] ""
    ]
]


I like the line with transpose, but is it possible to make it any more succinct?

See Reference Cucumber for documentation related to Cucumber
For this you could use a Scenario Outline, and I personally, would split that function into two separate functions.

Try doing something like this:

Scenario Outline: cannot access certain paths as roles
  When I access "&lt;path&gt;" as "&lt;role&gt;" 
  Then I should see an error

Examples:
 | path   | role  |
 | /path1 | user1 |
 | /path2 | user2 |
 | /path3 | user3 |
 | /path4 |       |


Scenario Outlines are used when you want to test the same fundamental thing, using different parameters, without clogging up your feature file with many Scenarios. 

They always use an examples table, and will run through the examples table replacing the placeholders (which will always match the heading rows), with the content of each row (as with a usual table).

In my opinion, this is the best way to test what you are attempting to do.

EDIT

In light of the comments below, maybe this would be the best course of action:

Scenario Outline: cannot access various paths as role 1
  When I access "&lt;path&gt;" as "user1" 
  Then I should see an error

Examples:
| path   |
| /path1 |
| /path2 |
| /path3 |
| /path4 |

Scenario Outline: cannot access various paths as role 2
  When I access "&lt;path&gt;" as "user2" 
  Then I should see an error

Examples:
| path   |
| /path1 |
| /path2 |
| /path3 |
| /path4 |

Scenario Outline: cannot access various paths as role 3
  When I access "&lt;path&gt;" as "user3" 
  Then I should see an error

Examples:
| path   |
| /path1 |
| /path2 |
| /path3 |
| /path4 |


It may be longer, but it is more human readable than perhaps the table would.