Recently, when reading Phoenix routing guide I stumbled upon description of resources:
scope "/", HelloPhoenix do
pipe_through :browser
resources "/users", UserController
end
And having Rails background I thought that it would be nice to get the framework guess the controller name based on path.
resources "/users"
Then I added matching function to deps/phoenix/lib/phoenix/router.ex
defmacro resources(path) do
controller_name = path # "/users"
|> String.replace_prefix("/", "") # "users"
|> String.split("_") # ["users"]
|> Enum.map(fn(el) -> String.capitalize(el) end) # ["Users"]
|> Enum.join() # "Users"
# create a fiction result of quote function
controller = {:__aliases__, [], [String.to_atom(controller_name <> "Controller")]}
add_resources path, controller, [], do: nil
end
After phoenix recompilation with mix deps.compile phoenix
new router function magically started to work.
# web/router.ex
scope "/", HelloPhoenix do
pipe_through :browser # Use the default browser stack
resources "/users"
end
scope "/admin", HelloPhoenix.Admin, as: :admin do
pipe_through :browser
resources "/users"
end
$mix phoenix.routes
users_path GET /users HelloPhoenix.UsersController :index
users_path GET /users/:id/edit HelloPhoenix.UsersController :edit
users_path GET /users/new HelloPhoenix.UsersController :new
users_path GET /users/:id HelloPhoenix.UsersController :show
users_path POST /users HelloPhoenix.UsersController :create
users_path PATCH /users/:id HelloPhoenix.UsersController :update
PUT /users/:id HelloPhoenix.UsersController :update
users_path DELETE /users/:id HelloPhoenix.UsersController :delete
admin_users_path GET /admin/users HelloPhoenix.Admin.UsersController :index
admin_users_path GET /admin/users/:id/edit HelloPhoenix.Admin.UsersController :edit
admin_users_path GET /admin/users/new HelloPhoenix.Admin.UsersController :new
admin_users_path GET /admin/users/:id HelloPhoenix.Admin.UsersController :show
admin_users_path POST /admin/users HelloPhoenix.Admin.UsersController :create
admin_users_path PATCH /admin/users/:id HelloPhoenix.Admin.UsersController :update
PUT /admin/users/:id HelloPhoenix.Admin.UsersController :update
admin_users_path DELETE /admin/users/:id HelloPhoenix.Admin.UsersController :delete
So the question is about ugly transformation that tries to mimic #constantize method in Rails. Is there a better way to guess the constant based on the given string?