Do you know Ruby on Rails? Did you come from Rails?
If so do you have any tips to share? Was there anything that helped your grok the similarities/differences? Any articles, books, talks/vids/screencasts, or courses (or even forum posts) you found particularly helpful?
Iâm likely not the best person to respond to this, Ruby & Rails was my first foray into development. Iâd been doing Ruby stuff for about 3 years but my first real job as a developer was with Elixir. As much as I love Ruby, the Elixir world felt pretty much the same but everything was demystified. No special magic going on under the hood, if I wanted to know how something worked I could just go to the module/function and find it.
Admittedly, this was most frustrating moving from ActiveRecord to Ecto, I missed all the out of the box magic ActiveRecord provided.
I think https://elixircasts.io/ was a big help when I was first learning Elixir (it still is sometimes). My office also had an older copy of Programming Phoenix I worked through a few chapters of.
Railsâs ActiveRecord will not force you to preload anything, unless you are using the strict_loading setting on your models, but you might risk running in n+1 queries when looping through the results
Ignore any notion you got that âElixir is Erlang for Rubyistsâ If you are coming to Elixir from Ruby, wipe this sentiment from your brain. Elixir merely takes the syntactic elements from Ruby that Rubyists love and brings them to Erlang (by which I mean the BEAM, of course)âthatâs it. The similarities end there. Seriously. The quicker you accept that the quicker youâll make progress. At least thatâs how it was for me.
In terms of Phoenix, for me it was to accept that Phoenix is nowhere near as opinionated as Rails is. That one actually took me a while. Phoenix is looking a lot less like Rails these days so this isnât as much of a thing. You can, however, bring the spirit of those concepts over to Phoenix to great effect, however, my second piece of advice here is donât get frustrated and try and jam specific Rails concepts into Phoenix. Just be uncomfortable for a few weeks and learn why things are the way they are, then you can break the rules if you see fit.
In terms of Ecto, it can be tough at first, but if you ever worked on a Rails project where a bunch of arel or raw SQL was necessary, Ecto will be a breathe of fresh air. I tell my Rails buddies that Ecto is ââŠlike an actually good version of Arelâ (sorry Arel devs, but itâs how I feel). I personally donât miss ActiveRecord even a little.
Not sure I agree with that (or that specific wording) Andrew
If Elixir isnât the Erlang for Rubyists, which BEAM language is?
Iâd agree that Elixir isnât Ruby on Erlang though, and that it only bears a superficial resemblance (under the hood itâs very much Erlangâs baby) but I do think Elixir helps give Rubyists some familiarity and thus comfort, even if just for the aesthetics. Hence thatâs what I think helps make it the closest (production-worthy) Erlang-language we currently have for Ruby users.
Well, when you put it like that itâs hard to argue with!
I certainly didnât mean any disrespect with my wording and I agree with everything you said. I was trying to word my answer as if speaking to a total Elixir n00b coming from Rails (eg, saying âErlangâ instead of âthe BEAMâ). When I was learning Elixir, I was under the impression that it was supposed to have a lot more in common with Ruby than just the syntax and itâs a sentiment Iâve heard from others several times over the past few years (mostly from non-Elixirist thinking that âElixir is basically just Ruby with better concurrencyâ).
Iâve noticed this too and itâs a good thing.
I recently did a moderately deep dive into Rails 7 due to job opportunities being how they currently areâthere is just more Rails stuff out there. Even so, I ended up back with LiveView because itâs so much simpler. Hotwire is really nice if you want to do full progressive enhancement out of the box, though.
Totally agree. I experimented a bit with Phoenix + Hotwire and I really liked it.
To me, Hotwire makes so much more sense to use with Phoenix.Components than it does with Rails views+partials.
Ya, if I ever get back to a certain project was working on I should switch to Phoenix + Hotwire. I was using Hotwire with View Component which is nicer than partials but itâs no heex (and Ruby is no Elixir).
I hear you. We use ViewComponent on my current job and its ok, what I really dont like is that we use haml.
Going from heex + vscode plugins to haml is pretty sad, the developer experience is so much worse
Not to derail this thread too much but I used to be really into Slim until I wasnât. One of my biggest problems was that back in a pre-Tailwindeque world I couldnât tell my markup from my css at a glanceâthey had an almost identical shape!
Iâve been doing Rails since 1.x. I like to tell people new to Phoenix that itâs most like Rails 2.x. Kinda back when Rails was simple (routes that sends requests to a controller/action, and also the whole ârestful resourcesâ thing).
That said, Iâm also starting to fall more and more into the camp of everything should be LiveView; thereâs no point in doing controller/actions anymore (aside from APIs), even if youâre just making basic CRUD pages. Even beyond no point, I actually think itâs easier to make basic CRUD pages in LV now.
To get peopleâs foot in the door with LV, I do a 10 min live coding session where I make a route, then setup a basic LV and show how to do assigns and wire up the HTML, etc. Then try to show the difference between connected? mount and dead mount and how it relates to progressive loading.
Iâm in the âeverything should be a LiveViewâ camp as well so long as your page doesnât need to work without JS. Making forms work without JS in LiveView is a pain and not worth the effort imo. But otherwise, I donât see the point in not doing everything as LiveViews. I agree that basic CRUD feels simpler in LV.
I think blitzjs or remix gets you about the same simplicity, just using js/node instead and no websockets needed (I may be wrong on websockets). I havenât used them, so this is just an abstract observation.
I worked full-time with Rails for around five years before switching to Elixir and Phoenix. Havenât regretted the decision for one second - I donât miss Rails at all.
If youâre coming to Phoenix from a Rails background, then the best course in my humble opinion is the one I wrote: Phoenix on Rails. I apologise for the self-promotion, but you can use the code ELIXIRFORUM to get a $10 discount.
To answer your question more directly, some of the main things that helped me were:
Taking the time to learn Elixir itself before diving into Phoenix. Elixir is much more different from Ruby than it appears at first; the languages use similar syntax but their underlying design is very different. I initially tried to learn Elixir âalongside Phoenixâ but it was confusing and too much to learn at once.
Understanding that (as someone else said above) Phoenix isnât nearly as opinionated as Rails is. If all you know is Rails, your initial reaction to solving a problem is often to try and figure out the âRails wayâ of doing it - like thereâs a single best practice that everyone should follow. This isnât the case nearly as often in Phoenix. In particular, your âcontextâ modules are just regular Elixir modules. In Rails, you build a Rails app; in Phoenix you build an Elixir application where Phoenix just happens to be the part that handles the âwebâ side of things (and Ecto handles data persistence/validation etc.)
This might seem like a bad thing, but I think over time youâll come to appreciate Phoenixâs flexibility. If anything Rails is too opinionated - itâs too inflexible, and the âRails wayâ breaks down and becomes a mess as soon as you try to do something that doesnât fit neatly within Railsâs conventions.
Before I learned Ecto I already had a good knowledge of SQL and knew how to write a complicated SQL query. This definitely helped me understand Ecto.Query, as its DSL follows SQL quite closely.
I think Ecto is the hardest thing to learn when coming from Rails - not because itâs difficult on its own terms, just that itâs very different from ActiveRecord; probably the part of Phoenixâs stack that feels the most unfamiliar to a Rails dev. (I also think that Ectoâs MUCH better designed than ActiveRecord and leads to far cleaner and more maintainable code, but thatâs another post.) Before you try to build a complicated Phoenix app, I recommend sitting down with the different parts of Ecto and getting to grips with how they work, and how to do in Ecto the basic things you already know how to do in ActiveRecord. (For starters, I wrote this cheatsheet) for learning Ecto.Query when you know ActiveRecord.)
Some other small things that are bound to trip you up, so be aware:
in HEEx you need to write <%= if instead of <% if.
uniqueness validations work differently; look up unique_constraint.
Ecto associations arenât loaded by default (you need to explicitly preload so you canât accidentally introduce an N+1 issue, as is far too easy in Rails.)
Iâd also recommend taking the time to understand Plug sooner rather than later. At a glance Plug is similar to Rack, except Rack is kind of hidden from you and you can spend years using Rails without ever needing to think about Rack. Plug is much more âup front and centreâ in Phoenix and an important part of your stack - you donât need to understand it from the very beginning, but donât neglect it.
Thatâs all I can think of for now. (As for the book Phoenix for Rails Developers that was mentioned above - I read it when I was getting started but honestly I was very disappointed by it, not least because itâs very out of date. Phoenix has changed a lot since 1.3. My disappointment with that book was one of the reasons why I eventually decided to create Phoenix on Rails.)
It has been years since I wrote any Ruby code, but one thing I do miss to this day is being able to do stuff like 1.day.ago to get a date object that represents yesterday. Coding patterns/structures that resemble natural language are such a simple yet powerful concept that Iâm surprised more languages havenât tried to implement them.