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

14 Likes

It’s pity that you didn’t come with this website three months before. We started new project with “windows ASP.NET” guys and, of course, me and my boys recommended a lot Elixir and Phoenix too. But, it’s failed. Because the installation these kind of stuff on Windows was big problem for them.
So maybe, it would be valuable to write a short info, how to install the Elixir and Phoenix on Windows, Linux or macOS.

I just a quick looked at to renttoday-database repo. It’s a lot of pure sql codes. Haven’t you consider to use Ecto for that? There is really nice book Programming Ecto.

Je hezke zde videt dalsiho cecha, at se dari :slight_smile:

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.

2 Likes

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.

1 Like

I was really surprised there is no native way in Ecto to call stored procedures. There is no natural way to do it in EF Core either but EF Core is simplier than its predecesor.

We use LLBLGen generator for our .Net applications but I’m planning to use their generator to generate Ecto models.

I’m using Elixir in my hobby project, I’m planning to use driver like MyXQL directly. If I was using Microsoft SQL Server then maybe I would use driver like https://github.com/livehelpnow/tds
I sometimes like to use multiple select statements but on Elixir side I don’t see many drivers supporting them. I read that in MyXQL driver they are disabled because MariaDB has some sort of bug related to them.

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:

1 Like

That’s just the thing. The separation of concerns you seem to dislike was reinforced because in many projects DB admins / sysadmins / programmers / designers / frontenders… all became one role.

You think I want to deal with hand-crafting complex SQL regularly? Hell no. SQL should be taught to teenagers – it’s an extremely useful to know how to query and insert/update data. But my main specialty is backend code and I just want to be left the hell alone to work on that. But I do manage with SQL when necessary.

However, many businesses want to pay 1 salary and get N roles. And while I am no longer working for such people – and it feels great! – many, and I mean a lot of people out there can’t afford to make that choice.


There are good separate SQL-only migration/rollback solutions out there. They work just fine. But most businesses hire cheap and/or junior programmers and a ton of them have no clue about raw SQL but they did learn their web framework’s du jour migration scripts.

I quite like the Ecto code you showed btw. It’s not that complex and to me it reads easier than the SQL counterpart.