Rails vs Phoenix

I don’t think that way of pundit (too implicit) is acceptable in FP point of view.
Though you could give a try to GitHub - cpjk/canary: 🐣 Elixir authorization and resource-loading library for Plug applications. (inspired by cancancan)

Hey there :slight_smile:

Yes I know a lot of these projects but I still find them… lacking. Plugsnag for instance doesn’t handle channels and has some other problems which is why we wrote bugsnex. Appsignal just added very rudimentary support for channels, before there was none. newrelic.ex is fairly new and I haven’t had a look at it yet etc. - I know the ecosystem is moving forward but it’s still a stopping point for me sometimes as some of the solutions are also not as battle tested yet. E.g. as you point out in the README the older newrelic agents suffered from some problems.

All that said, I see it moving in the right direction and also heard whispers of other performance monitoring services adopting Elixir/Phoenix :slight_smile:

I agree. These projects provide only part of possible features, but the current situation is much better than a year ago… So it’s in our hands :slight_smile:

ha definitely! Even than ~ 7 months ago (when we started our Phoenix project) and hearing also how companies want to support it all around. Was happy to see in the missing libraries and tools that someone is already working on PayPal integration!

2 Likes

Thank you for the recommendation. My experience of cancancan was that it was great for smaller projects; however with larger projects it was not so good; mostly in terms of runtime overhead.

Rails has a joy in the wealth of GEMs available but it can be a major task to work out which, if any will be suited to a project and actually go the distance.

canada is based on protocols, so quite fast, the only slow part might be what you do for the checking, but even that is done concurrently (unlike in ruby). :slight_smile:

4 Likes

I don’t know if you found it already, but the lib you are searching for is named bodyguard.

1 Like

Thank you kindly sir - much appreciated.

1 Like

Haven’t read this yet, but it might help folk who’d like to compare the two:

4 Likes

Cool link, but holy hell that popup ad on their page that appeared after a minute needs to die, hate hate hate hate those things…

4 Likes

I also like this post by Rafał Radziszewski in response to this answer in a Quora session with DHH:

(Jump to the last paragraph if you’re feeling lazy)

[quote]
Short answer: yes, it’s definitely reasonable assumption.

Long answer:

The main thing about Elixir is that it’s not like Ruby at all. When I was about to start using the language, I had the opportunity to talk to Jose Valim (language creator) on a conference and I asked him what his advice was to start with. At the time I was a RoR dev with a year of software house experience and a few projects on production already done. He told me: “you must remember, that it looks like Ruby, but it’s not Ruby at all”. Though simple, it was the best advice I have ever received.

First of all, Elixir is functional. Not getting into formal definitions and stuff, what it means is you’re going to write code in much different way that before. No longer will you iterate over array changing it elements one by one and then return the same array. No longer will you mutate state of object(struct). No longer will you create hierarchies and inherit stuff. What this means is many ways you used to solve problems will be no longer available to you.

Personally, it was not that hard for me, because as it turned out, I started to do quite a lot of things in functional way in Ruby before. For me, it was quite often simpler and more “natural” solution, but I know quite a lot of people who had issues with that - depends on how your brain is wired I guess.

Second thing is, you’re going to need to learn new ways of doing stuff. Pattern matching, map, filter, streams. Grokking the fact that “=” is now pattern matching, not assignment and the consequences of that. Getting used to tuples and structs. Using modules as main code entity. The list goes on and on.

Third thing is getting to know Beam VM. This means understanding Elixir model of concurrency, grokking processes, understanding how to use GenServers. This is fun, but might take you a while to process. Most of the people are not used to thinking of your code in terms of different processes and async operations. I know I wasn’t. To this day I do not consider myself proficient in that area.

So the question you have in your mind now is probably along this lines: “why bother”? Why would you spend so much time relearning your basic problem solving skills instead of being productive in what you already know?

In my case, the answer is: it is SIMPLER. Yeah, really! Once you start grokking this thing, it will time and time again prove to be easier to do stuff. You want to know why some function does not behave in a way you think it should? You check the source of the FUNCTION. You do not care about state, you do not care about previous operations. You just check the function.

You debug stuff? It’s easy to see what’s going on in any given state. Variables are immutable, so you know for sure what is the state of one for a given set of starting parameters. You just need to add breakpoints along the way to see where it stops behaving like you wanted and the error is likely to be easy to spot.

You decide that you want to refactor? Cool, because it’s just functions. You can move them around and fix namespacing. There is no state you need to be worrying about.

Finally, you want some concurrency? You’re welcome. Adding messaging feature to your app is a day’s work, and that’s only because frontend takes some time usually. It’s so simple. The same for adding some temporal storage and many other features. Finally, you can keep state in isolated areas, that you make as simple as possible and about which it is quite easy to reason. Actor model is a sensible solution. Concurrency is fun, instead of terrifying.

And when we get to frameworks and libraries - Phoenix is simple too. No monkey patching. No over-abstracted functions nobody understands without spending an hour staring. No hidden state and no gotchas. Just a bunch of functions tied together, that’s how simple it is.

So yeah, I believe more people will move to Elixir. Not because it’s more performant (though it is and it means that you have longer run before you actually need to start optimizing), not because VM has nice features (though it has, hot-deploys possibility being one of them), not because you can actually write efficient concurrent code (though you can and using one of top industry solutions). I believe people will move, because it’s actually simpler. Simpler in a good way, like Unix is in many ways simple. And simpler means less time for wondering “what the f*** is going on here” and more time for actually writing cool stuff. [/quote]

7 Likes

Assuming one is building a fairly vanilla, server-generated HTML web application, what does Phoenix do better than Rails? Where could Phoenix use some improvement? I’ll start:

Things I love about Elixir/Phoenix when compared to Rails:

  • The explicit nature of FP seems to improve code clarity. This is most noticeable when I modify old code or review someone else’s code.
  • Plug is more user-friendly than Rack. Pipelines allow for a zen-like simplicity of request processing.
  • Speed. I don’t care so much about getting every last ms out of response times. I do care about lowering server costs without sacrificing productivity, and I think Phoenix gets this right.
  • Community. The Ruby/Rails community is great, but I don’t think it’s as great as the Elixir community :smile:

Things I don’t love about Elixir/Phoenix when compared to Rails:

  • Deployment. I would love to have Heroku-like deployment that’s compatible with all the OTP goodness.
  • Libraries. Elixir has a lot. Ruby has a metric tonne. :slight_smile:
  • Books, blogs, and searchable knowledge. Ruby/Rails has more of it, by virtue of its popularity and age.
  • Initial development speed. I have more initial productivity with Rails, but maybe that’s just due to familiarity.
  • But mostly deployment.
2 Likes

Could you be more specific about what you think is missing in terms of deployment? Maybe it’s already there :slight_smile:

Rails (and AR) is better because: more magic. If you know it, you can make stuff incredibly fast.

But, do you remember you first days with Rails, trying to understand why is it working? I do remember that nightmare.

So, Phoenix (and Ecto) is better because: less magic. It is way more readable and easier to learn. Few more lines won’t kill you, and could make all the stuff clearer.

2 Likes

While it might not matter for a world crushing startup, or a personal site, if your site is somewhere in the middle its reduced resource need will let you scale up much cheaper. As opposed to Rails where you will have to add capacity constantly. So if costs don’t matter go ahead but if you want to add a site that can pay its bills with AdSense go with elixir.

And I think elixir deployment is much easier. Maybe not on Heroku, but keeping a Passenger instance of Rails running and up to date is a huge PITA. Elixir can get bundled into a runtime package that includes the Erlang VM. No server requirements at all.

2 Likes

People who say that deployment is harder with Elixir than with Ruby, have forgotten or never even experienced the huge, huge PITA that Capistrano can become.

Often times I just feel that many Rails devs just don’t know anything different than Heroku and don’t want to be bothered with servers & infra. From my personal experience, this is a lot different in other communities, where people tend to deploy on their own servers.

1 Like

This is something I’ve been thinking about a lot. Some points:

  • Streamlined way to deploy (and hot deploy) to an elixir cluster that automatically finds other nodes, nearer to the simplicity of Heroku. Obviously hot deploys are just by their nature more complicated, but I’m having trouble finding something between the gap of AWS’s “build your own thing from AWS nuts-and-bolts” and Heroku’s uber-simplicity. There’s a couple startups attempting to do this, but it’s hard to trust your infrastructure to these smaller companies ATM.
  • How does one set up configuration for staging vs. production environments? Are configs built into the app binary at compile time, or are they loaded from ENV vars/erlang config? (the answer to this largely depends on your build tool, it seems)
  • Where does one store their “app secrets” to make secure-but-available to the app servers? This is more of a general devops problem (of which there are many, many solutions), but I often feel like I’m reinventing the wheel as I manually set up all this stuff. Also, the solution somewhat depends on how configuration works with hot deploys. How can a changed ENV var be injecting into an already-running application? Is that even a thing? Is it better to use an erlang VM config of some sort (link), and how does that work on when you need to change a config while it’s running?

All of these questions have answers, of course, but there’s often a dozen different solutions for each step, some of which compose well/poorly with solutions to other steps. It’s easy to get lost in it all. Happy to hear other’s feedback on strategies/services they use to streamline/simplify some of this stuff!

2 Likes

Blazing fast tests. I cannot stress how important that is.

I recently got to compare a Phoenix app with about 1.5k test that run in about 30 seconds and a Rails app with about 1k test that run in 8 minutes. Both have a similar setup where most tests hit the database.

It’s a huge quality-of-life improvement working on one vs the other. Faster tests mean you can rely more on the tests and run them more frequently besides saving a ton of time. I’m primarily writing JSON APIs - most of the time I don’t even start the app - I just write the tests and run them constantly.

9 Likes

This is also one of the biggest things for me.

I would also highly recommend https://github.com/schrockwell/bodyguard the update to work with Contexts is great!

1 Like