thorn

thorn

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?

Showing Posts 1 to 2

christopheradams

christopheradams

The Phoenix.Naming module has something like this.

path
|> String.replace_prefix("/", "")
|> String.split("/")
|> Enum.map(&Phoenix.Naming.camelize/1)
|> Enum.join(".")

Or take a look at Macro.camelize/1 if you can guarantee your routes can be cleanly turned into module names.

christopheradams

christopheradams

In addition, if you really want this feature (to each his own), you don’t have to edit your Phoenix dep to get it.

As long as you’re willing to come up with a new name and not use resources, you can create your own macro in your router that takes a path and translates it into resources "/users", UsersController.

Something like:

defmacro clever_resource(path)
  controller = .... # like your code above
  quote do
    resources unquote(path), unquote(controller)
  end
end

Then in your router you call it with:

clever_resources "/users"
— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
marciol
It would be helpful to have a list of companies worldwide that hire engineers without prior experience in Elixir. Often, it can be quite ...
New
durvia
Anyone running long-lived stateful processes on BEAM? We’re building an AI agent runtime and would love to compare notes. We’re a small ...
New
nseaSeb
I’ve just put together a small POC exploring PDF inspection from Elixir/Phoenix: The idea is pretty simple: drag &amp; drop a PDF in a...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews