Repository: phoenixframework/phoenix (elixir)

Issue:
Confusing error message when resources singleton: true and only: [:index]
<!--
### Precheck

* For help and support, use Stack Overflow or the Phoenix Talk mailing list
* For proposing a new feature, start a discussion on the Phoenix Core mailing list
* For bugs, do a quick search and make sure the bug has not yet been reported
* Ensure that this issue is related to the Phoenix library and not one of the dependencies listed in mix.exs (Ecto, Plug, etc.)
* All checked? Be nice and have fun!
-->

### Environment

* Elixir version (elixir -v): 1.4.5
* Phoenix version (mix deps): 1.2.3
* NodeJS version (node -v): v6.9.4
* NPM version (npm -v): 3.10.10
* Operating system: MacOS 10.12.6

### Expected behavior

I came across a confusing error message, when I try to do:
```elixir
resources "/settings", SettingsController, singleton: true, only: [:index, :update]
```

the error message: 
```elixir
== Compilation error on file web/router.ex ==
** (FunctionClauseError) no function clause matching in anonymous fn/1 in :elixir_compiler_36.__MODULE__/1
    web/router.ex:2: anonymous fn(:index) in :elixir_compiler_36.__MODULE__/1
    (elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2
    (elixir) lib/enum.ex:645: Enum.each/2
    web/router.ex:83: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
```

Scratched my head for a while, after reading through the doc I realized when `singleton: true` there is no `:index` actions.

### Actual behavior

I feel maybe the error message could be a little bit better? I would like to help :)


Pull request description:
Raise error when declaring singleton with index
Fixes #2575.

Patch:
diff --git a/lib/phoenix/router.ex b/lib/phoenix/router.ex
index 1fac62212..51cf07b82 100644
--- a/lib/phoenix/router.ex
+++ b/lib/phoenix/router.ex
@@ -234,6 +234,7 @@ defmodule Phoenix.Router do
 
         if resource.singleton do
           Enum.each resource.actions, fn
+            :index   -> raise ArgumentError, "singleton resources cannot have an :index route"
             :show    -> get    path,            ctrl, :show, opts
             :new     -> get    path <> "/new",  ctrl, :new, opts
             :edit    -> get    path <> "/edit", ctrl, :edit, opts


Test patch:
diff --git a/test/phoenix/router/resources_test.exs b/test/phoenix/router/resources_test.exs
index 25ac6f489..1bfe3a3fd 100644
--- a/test/phoenix/router/resources_test.exs
+++ b/test/phoenix/router/resources_test.exs
@@ -266,4 +266,13 @@ defmodule Phoenix.Router.ResourcesTest do
     assert conn.resp_body == "show users"
     assert conn.params["id"] == "2"
   end
+
+  test "singleton resources declaring an :index route throws an ArgumentError" do
+    assert_raise ArgumentError, ~r"cannot have an :index route", fn ->
+      defmodule SingletonRouter.Router do
+        use Phoenix.Router
+        resources "/", UserController, singleton: true, only: [:index]
+      end
+    end
+  end
 end