OndrejValenta

OndrejValenta

Intophoenix.io - our how-to site for ASP.NET programmers

Me and my boys started a new website specifically designed for other ASP.NET programmers that struggle, as we do, with their transformation to Elixir/Phoenix programmers.

Although Elixir and Phoenix are both praised for their simplicity and Phoenix even share some ideas and concepts with ASP.NET it’s quite different in the way you have to think about stuff and structure your projects. I’m pretty sure that once a programmer see the whole picture he realizes it actually was true and both Elixir and Phoenix are simple, even simplier tha ASP.NET. But before he gets there he struggles as we do and that’s why I decide to start this website and show how things are done in ASP.NET and comparison how they are done in Phoenix and Elixir/Erlang respectively.

We say in Czech republic that only the one who can explain to someone else how something works truly understands it, so by trying to help others we have to learn it ourself.

It’s still heavily work in progress. We started like 10-14 days ago and I had to rework a little bit Pagila sample database but we’d like your opinion, correction, participation. Be our guest..

Just an example of our first surprise. In ASP.NET there are sections in masterpage that you can name, say ScriptsAfterBody, and then when you have a Razor page that needs to render some Javascript after all is rendered you just use @section ScriptsAfterBody { and you put your scripts here }. As you can see here: https://stackoverflow.com/a/13089572 ASP.NET had it way back in 2012. I’m pretty sure this can be done in Phoenix as well but we are still looking for the most effective way. And to save time for the others we will put it on our website.

I’m looking forward for your feedback. Positive and negative, they are just different sides of the same coin.

Ondrej

Most Liked

OndrejValenta

OndrejValenta

That’s a good idea. There should be an installation guide. I’m not sure if you mean for production or for development but we are still looking for “best” IDE.

I tried to use RubyMine but now I’m using IntelliJ. I was missing some keybinding options in RubyMine. But we also use VS Code and Spacemacs, although that is for nerds :slight_smile: .

To programming in Ecto. I’m simply no fan of code-first approach. It’s the same story as with Entity Framework. It’s based on the idea that anyone can create databases without the knowledge of their inner workings. While this is true for Ecto and Entity Framework, it truly creates databases on it’s own, the only way how can they achieve this possibility for so many different database engines is to be quite general. So you have this huge powerhouse named Postgres at your disposal and you use like 10-20% of it’s power just because you don’t have to use SQL.

Look for example at this article.
Why would anyone think that the code below is better than to have a stored procedure/function and make a simple call to it.

articles = Repo.all(
  from c in "articles",
    join: sq in fragment("(SELECT ts_rewrite(plainto_tsquery(?), 'SELECT * FROM aliases') search_query)", ^term),
    on: fragment("search_vector @@ ?", sq.search_query),
    where: not is_nil(c.publish_at)  and c.static == false,
    order_by: fragment("rank DESC"),
    select: %{
      id: c.id, title: c.title, slug: c.slug, display_date: c.display_date, 
      rank: fragment("ts_rank_cd(search_vector, ?, 32) AS rank", sq.search_query),
      introduction: fragment("ts_headline('english',CONCAT(introduction,' ',main_body), search_query, 'StartSel=<mark>,StopSel=</mark>,MinWords=50,MaxWords=100') AS headline"),
      tags: c.tags
    })

But there are other reasons I don’t like this approach as well. For decades we were taught to separate our concerns, to have system boundaries that just have public interfaces and so we created stored procedures, precompiled pieces of database code, and we’ve been calling them. Database owners could rework whole database without us knowing and even care but then Linq to SQL and Hibernate came and told us we should not separate concerns anymore and instead lock our databases in application code.
So now when you want to update simple thing in database you have to redeploy your whole application. That simply cannot be better.

And the last point, one of the benefits of using Ecto or EF or what have you is that you can switch your database at anytime. You can use MS SQL today, Postgres tomorrow and mysql the day after but in my 15 years of professional programming I don’t remember any project that would do that. And I have been to plenty. I’m not saying it’s not happening but how often it actually does? Is this really a valid point?

I’ve just remember one more thing, rollbacks in migration scripts. With ever increasing pressure to go full CI/CD and can easily imagine a situation in which someone who is not familiar with how things work just go to his CI/CD tool and presses “Rollback to version” button and his CD will truly rollback to some previous version of an application without any problem. Everybody is cheering and happy to the moment they realise rollback also meant to remove tables in their database. :japanese_ogre:

So we will cover usage of Ecto in all ways in https://intophoenix.io but internally try to have as many stored procedures as possible.

P.S.: I was one of the people who believed it’s a good thing to use EF but then I realised it’s actually a false marketing and they are dragging me down because I’m unable to change anything without a full migration of my application.

A ano, je milé vidět, že nejsme v tom Elixírovém boji osamoceni na českém poli. Budu se snažit dostat Elixir/Phoenix do České pojišťovny. Je to takový muj vnitřní cíl.

wanton7

wanton7

So many hours wasted using NHibernate and now some with Entity Framework Core. Quite likely going back using Dapper and good old SQL. Having ability to design your queries in SQL is golden and you don’t have to on mercy of some SQL translation layer that could cause slow queries that are hard to fix. If you can even fix them without raw SQL.

ondrej-tucek

ondrej-tucek

It can be write for both cases :slight_smile: I use to VS Code and I’m satisfied with him. I thought that vim is for nerds :slight_smile:

I get your point. But in general, there are different syntaxes between these database engines. So after all then you have to rewrite sql code too. I don’t say that to rewrite all, but somewhere do.

I’m not sure, if it’s good example of Ecto using. As author of this example said two years ago:
“Just try working with it directly in a pg console or sql editor. … I’m trying to find some time over the next couple of weeks to upgrade to Elixir 1.5 and Phoenix 1.3, set things up properly with contexts,…”

I think an important thing here is the context. And also pity that the author hasn’t released the codes yet. Because via context you can establish, for example CRUD implementation. Then you can do it as in our case read_patient.ex e.g.

...
@spec all() :: [Patient.t()]
  def all() do
    Patient.all()
    |> Patient.ordered_by_surname_and_name(:asc)
    |> Patient.ordered_visitations_by_date()
    |> Repo.all()
  end

  @spec search(String.t()) :: [Patient.t()]
  def search(query) when is_binary(query) do
    query
    |> sanitize()
    |> add_prefix_and_suffix()
    |> Patient.search()
    |> Patient.ordered_by_surname_and_name(:asc)
    |> Patient.ordered_visitations_by_date()
    |> Repo.all()
  end
...

where for instance

  @spec ordered_visitations_by_date(Query.t()) :: Query.t()
  def ordered_visitations_by_date(%Query{} = query) do
    v_query = from(v in Visit, order_by: [asc: v.date])
    preload(query, visitations: ^v_query)
  end

So his context could be in this spirit (more readable, more reusable functions,…) :slight_smile:

I think the Ecto migrations can help to save a lot of nerves. As it’s mentioned at Ecto book:

Migrations solve an age-old problem: keeping the structure of the database
in sync between production systems, staging systems, and the local systems
running on each developer’s computer. This used to be a manual process and
it was prone to error. A hot fix made on a production system might not
propagate back to the developer’s systems, leading to errors that were hard
to track down. Migrations help automate this process and provide a consistent
framework for making changes across all the systems in your organization.
When adding a new feature that requires changes to the database, you write
a migration: a single Elixir module that can execute the changes you want to
make. You store that migration in source control along with the rest of your
code. When you run the migration on a particular database instance, Ecto
makes the changes specified in your migration to that database, and keeps
track of which migrations have already been run.

Wow tak to drzim palce at to vyjde! :+1:

Where Next?

Popular in Guides/Tuts Top

Zurga
In a quest to optimize the amount of data sent between the server and client I recently decided to try to use MessagePack instead of JSON...
New
redfloyd
Greetings fellow alchemists ! I have started to write an open-source interpreter in Elixir (GitHub - nicolasdilley/dwarf-interpreter: Th...
New
annad
I’m posting this for developers who are totally new to Phoenix like myself. This is all probably obvious to more skilled Phoenix develope...
New
njwest
Greetings: I just wrote a step-by-step guide on building a Phoenix 1.3 JWT Auth API with Guardian JWTs and Comeonin password hashing. I ...
New
georgeguimaraes
Another cool plugin for Neovim, GitHub - jmbuhr/otter.nvim: Just ask an otter! 🦦 · GitHub makes it possible to run linters for embedded c...
New
yeshan333
vfox (version-fox) is a popular general version management tool write in Go, and the plug-in mechanism uses Lua to achieve extensibility....
New
sergio
Hey there, we’re going to walk through deploying a Phoenix app to a DigitalOcean droplet, manually - no tools no nothing. Just straight u...
New
bitli
In case this is handy for other people, here is how you can run Elixir on Android: Install https://termux.com/ apt update; apt upgrade ...
New
dmitriid
This is not a question, but a post for anyone who may need it in the future. Sometimes some browsers may mangle the filename if it’s non-...
New
GenericJam
Just leaving some breadcrumbs for future me and future others like me. Connect with TCP (not secured) - most servers will reject but use...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement