Why do we need name of the App everywhere in Phoenix?

web-frameworks
conventions
phoenix
Tags: #<Tag:0x00007fbcac2b5b18> #<Tag:0x00007fbcac2b59d8> #<Tag:0x00007fbcac2b5730>

#1

I’m not an Elixir or Phoenix professional in any way. I’m just a noob, a starter, but I want everything a bit simpler.
I was reading Programming Phoenix, and these thoughts came to my mind.

  1. Why do we have defmodule RumblWeb.UserView do and not just defmodule UserView do? Why do we have this AppName prepended everywhere?
    Isn’t it better not to have the AppName prepended?
  2. Why do we have Rumbl.Repo? Why don’t we have simply Ecto.Repo?

I think Rails have this kind of conventions because there it’s OO and in OOP you have that object (for example called Rumbl) and you have everything attached to that object, but here we don’t have objects, so why prepend this thing to everything and have extra burden on brain.

I’ll say once again that I’m a noob and I might be wrong, but again I think it will be easier for Noobs to adopt something if it’s simpler, and we should leave Conventions (and copying Rails) aside if it can make it simpler.


#2

There is no obligation to name this like that, You are free to use simply UserView if that is what You prefer. It is just a convention.

It does not even reflect folder structure. It’s just a convention, making it easier for us to think about some kind of namespace hierarchy.


#3

The answer is quite trivial: to avoid module name conflicts with the standard library, other libraries and some other code you might import into your project.
Aliasing makes this much less annoying than it initially seems.


#4

What do you comment on the complications caused by Repo?
In some places you have to deal with AppName.Repo and in other places you have to deal with Ecto.Repo. For a noob like me, it’s really hard to get my head around where should I deal with which of these two.


#5

As @michalmuskala said, aliasing allows You to use only Repo.


#6

Is it possible to make it so it have only Ecto.Repo everywhere instead of AppName.Repo. That will make it simpler.


#7

But I still know that I have two of them with the same aliased name. Like having two students in the classroom with the same name.


#8

IIRC there’s only one place where you actually use the Ecto.Repo module and that is inside the AppName.Repo module’s use call. Everywhere else you call your custom module directly.
The reason for that particular design is that it makes it trivial to connect to multiple databases at the same time - for each database you have a separate repo module - this is very complex in Rails because of the global nature of database connection.


#9

Aligning with the points brought up by others (avoiding naming conflicts), a clear advantage of this naming convention is that it also makes it easier for you to understand your code base as a whole (even if it might feel slightly more cumbersome for you now).

In this particular case, seeing a module name prepended with “RumblWeb” immediately tells you that this module deals with the Phoenix part of your application (the router, controllers and other web interface -specific bits), while seeing a module name prepended with just “Rumbl” would tell you that you’re dealing with the actual business logic part of your application.

The same points apply to your question about Ecto, too. Seeing code that refers to the “Ecto” module (such as Ecto.Repo) tells you that this particular line of code is working directly with the actual Ecto library and not your own code (which is made clear by the fact that you’re referring to AppName.Repo instead). @michalmuskala already pointed out why and how the two differ, but here’s an extra look from the understandability perspective as well :slight_smile:


#10

Thank you all! :slight_smile:


#11

Also just as more information, a module name is just an atom:

iex(1)> is_atom(:blah)
true
iex(2)> is_atom(Blah)
true
iex(3)> is_atom(Blah.Bloop)
true
iex(4)> is_atom(:"Elixir.Blah.Bloop")
true
iex(5)> :"Elixir.Blah.Bloop" == Blah.Bloop
true

You can actually use any module name that you can imagine. By default a capitilized atom name without the : just becomes that normal atom but with an Elixir. in front of it (to keep things unique), but as you can see you can specify it directly too, but using normal atom syntax you can make a module name just about anything you want. However, things like alias specialize on the dotted form to let you alias things more easily among other things in Elixir, it is just a convention, but the real Power is significantly more powerful (not that you should use it). :slight_smile:


#12

That is exactly why You want to use namespace, to avoid having two libs with the same module name :slight_smile: