For shipping new products or testing out ideas, I have not come across a more optimal framework in terms of going from idea to market.
Most often I've tried Phoenix, Django and Laravel as alternatives, but all of them seem to fall short. I gave .NET MVC a shot too back in its early days, it was not pleasant.
I run a dev shop and it seems to fit really well with our business model.
Does the bloat matter in the end tho?
You can build a million dollar business on a single $20 / month DigitalOcean server to run everything with tens of thousands of users. That's what Chris did from https://gorails.com. We talked about his Rails driven tech stack on the Running in Production podcast.
Recently he tweeted out he generated a million dollars from his business.
If you can get 100ms or less p95 response times without a complicated infrastructure then the only thing that matters is the ecosystem, community and how much you enjoy using that technology. If performance is a web framework's biggest feature then I think they're fighting an uphill battle. Performance isn't that important for most applications as long as you can produce a nice feeling application that responds quickly. All modern frameworks have a means to do that. Now it comes down to how fast can you build it and how nice is it to maintain.
Also, since you are all into ruby, maybe take a look around as to why other languages exist.
> maybe take a look around as to why other languages exist.
I've been around. Still like Rails, works well for me. Thanks for the advice :)
Not to mention, if you’re a solo developer or a small team, picking a language everyone knows and likes absolutely is a good reason. It’ll save you a lot of time.
Now I'm not saying you can't ever grow out of your friends (or languages), I just haven't outgrew Ruby.
If it didn't, surely he'd hate it, no?
I agree rapid prototyping is an excellent point for RoR but when you need to actually evolve the project for years, it gets really tedious and hard.
So for a dev shop RoR is quite fine -- you make the project, do very little iteration on it, and ship. That works well and I've experienced it.
For longer-lived projects however, Phoenix is miles ahead. Even Rust's Rocket, but only if you are willing to invent a lot of stuff yourself (auth for example).
I can't speak to Phoenix, but I've looked into Rocket and don't understand how it can really be compared to Rails. There's so much you need to implement yourself that you'll end up spending a big chunk of time on implementing things that Rails (or high quality / well used gems in the Rails ecosystem) can provide for free. And don't get me wrong, I'd love to sit down and do that work, but my job is to make stuff work and make it work quickly, and my employer doesn't hire enough people that we can afford to dedicate that kind of time when it's already "solved" by a framework.
I tend to work on projects where the requirements change constantly, and they're never really "done." Saying rails is good for "prototyping" is not wrong, but in a world where software is always evolving, the features and capabilities that make Rails great for prototyping are also great for just day-to-day existence.
With each new version of RoR gems just stop being compatible without replacement, and its a fairly significant effort to migrate everything to the new shiny being introduced. In fairly stable projects where there isn't much feature churn/replacement, you pretty much have entire sections of the codebase that never move past the version they were originally written in. You're constantly maintaining controllers/models written in RoR 3.2/4/4.2/5/5.1 styles since its incredibly difficult finding which features were used, but they still kinda sorta mostly work, until they silently don't.
The difference compared to other frameworks/languages is that Rails is very heavily powered by "magic". Every other tech explicitly configures and calls features being used, but Rails is mostly held together by "convention", but convention evolves. How do you search for things like "the filename of this must match the class name of this" or "the method name must match this database feature". Nevermind the metaprogrammed methods that aren't documented anywhere. The convention evolving as developer preferences changes is generally a good thing and keeps RoR from becoming too dated but it is an expensive maintenance burden.
I quite like Rails and it's still my first choice for personal projects/prototypes. But I'm definitely souring to it for long running professional work.
Furthermore, as the project grows, you need to introduce something more/bigger than MVC and people put these files everywhere. Sure it's a management problem but it doesn't help that people don't do the right thing by default.
In general, there's a breaking poing that you will very soon hit when you try to just pile things on top.
It's mostly the "magical" parts like before/after hooks.
I guess when you get into inheritance perhaps. When you have an inheritance chain, which hooks are firing and in which order? That gets confusing fast. But, that also doesn't feel Rails-specific at all to me.
Rails gives you some ways to shoot yourself in the foot, but what language/framework doesn't?
When you are tracing a bug and are trying to do step-by
-step debugging, it has been hell.
I have an expansion set up in my text editor that spits out `Rails.logger.debug("[jbootz] ")` and then I just do `tail -f log/development.log | grep jbootz`. I also have iTerm set up to highlight any lines containing "jbootz", so it stands out when it's mingled in with other output. (I just picked "jbootz" as it's a unique string)
In general that's the strategy for Rails debugging or really any dynamic language where the editor/IDE can't reason about the code like it can with a static language.... lots of debug output and then get a little creative with how you filter it in your terminal.
Helps to use an terminal app like iTerm that lets you use split panes so you can look at multiple filtered views of your log output at once if you like.
Quickly jumping to definitions? Even RubyMine can't do it.
Still, as far as definitions go? I don't know. I just grep for "def foo" (if I don't know what file it's in) or use my editor to jump right to the file where it exists (if I know where it is, which is usually the case)
Not as slick as the editor/IDE actually being smart, but I don't really find it to be a friction point.
... that seems unnecessarily complicated compared to using byebug, or hell, the RubyMine debugger.
I use pry/byebug extensively as well.
There are times when I prefer debugging via debug output statements and times when I prefer interactive debugging.
But any large enough project needs rules for placing files/classes
I don't see how Rails failed in that way
I do agree there are some "magical" stuff like hooks that can be easily abused and introduce bad coding habits/patterns
Wish I can turn them off per class (not for the whole app since they are still sometimes useful)
I don't see how that's a Rails-specific problem.
Before Rails, working in the wild and wooly world of Microsoft web dev (with occasional PHP thrown in) I saw some real horrorshow web apps. People hacking together their own confusing and misthought architectures. And those horrorshows were rule and not the exception.
The standardized structure of Rails apps is such a breath of fresh air. It's so nice to step into a Rails codebase and basically know where most things are most of the time.
Admittedly it's also nice to step away from Rails for smaller, simpler apps.
Generally each web app had its own organizational structure. Everything was still "page-based" so your site's file structure would mirror the actual URLs: the code for your product page would be "/product.asp" and your shopping cart page would be "/cart.asp" or whatever. Those files had intermingled markup and code extremely similar to ERB files in Rails.
Conscientious developers of that era would of course extract as much functionality as possible into shared include files. Even in those savage days we tried to separate logic and presentation whenever possible. Early PHP dev worked much the same way.
Needless to say this generally lead to spaghetti code. You certainly could make very maintainable ASP/PHP sites, with a lot of effort -- just like you can find some very maintainable and well-structured shell scripts. But, even so, each "well-structured" ASP/PHP site would have its own structure and it was quite a learning curve jumping into a new one, if you ever had to look at somebody else's code.
Early ASP.NET apps used an even more bizarre set of Microsoft constructs. Code-behind files, etc. Yuck.
Later came ASP.NET MVC which was quite good IMO. It borrowed liberally from Rails which was a good thing.
In Ruby land I developed with both Sinatra and Rails. Sinatra is great and a lot of fun, but you are totally on your own w.r.t. structuring your app. Once your Sinatra app grows past a certain complexity, you will generally just find yourself reimplementing large parts of Rails and encountering the same problems w.r.t. structuring your app.
Rails and MVC are not perfect -- many say other variations like MVVM/MVP/etc are better. Perhaps so. I've certainly had pain points with Rails (too much "magic", high RAM usage) but as far as structuring my applications.... no.
Alternatively are there some good "kitchen sink" open source projects that implement many of the typical web application features like auth, uploads, etc. ?
Companies like thoughtbot have been a gold mine of information and battle-tested practices - is there anyone similar in the Phoenix space that's worth following?
For auth, the core Elixir team has made one prototype but I am not sure if they'll pursue it further. Outside of that, use Pow. For file attachments: Waffle. Authorization: CanCan, although the area has several very solid options, I heard.
Discoverability can indeed be a problem. Covid-19 hit everything pretty heavily and Elixir's community is no exception. Just a month ago people started finally hiring for it again (on the forum).
This answers your question indirectly. I’ve included a link below to Amber Web Framework, built on Crystal. Crystal is a statically typed language with the speed of C and the exact same syntax as Ruby.
Check out the video a couple screens below, and you’ll see a demo of how quickly an Amber Blog App is generated. You’ll notice their is almost no difference between Rails syntax and Amber syntax.
I would be very careful with that statement, because it's simply not true (example: no type-related syntax in Ruby).
Spring Boot doesn't tick ALL the Rails boxes (Scaffolding a backend CRUD admin interface, all of the complex templating stuff - although Thymeleaf is pretty darn good) I'd put my money on it being more maintainable a year later. Spring as an ecosystem is huge, so there's always a strong possibility someone else has already solved the problem you're trying to solve. The tooling is pretty fantastic as well. Kotlin as a language is just fantastic.
Note to self - dont post about Java on HN, people downvote even non hateful comments!
Otherwise, I'm excited to try this out. I don't really have any performance-sensitive ruby personal projects, but with time and improvements pushing this to a production-ready state this could be a lifesaver in production for computationally heavy parts of a rails codebase.
Keep Ruby as it is - slow and expressive. If you need to speed up, get faster hardware.
Why not try to make Ruby faster without changing how expressive it is? I don't think this project does that by the way - it breaks Ruby semantics - but let's aspire to make Ruby faster.
> If you need to speed up, get faster hardware.
If your code is still too slow for your required per-request latency on a top-of-the-range Xeon and your individual requests have no useful parallelism and are not memory or IO bound... where do you go from there? Where are you getting faster hardware from?
Sometimes there is no faster hardware.
There may be some benefit to ultra specialized for this project to live in still but the audience is going to be quite niche.
So if I need to speed up my Rails application on a AWS, GCP or Azure instance, you're telling me in order to increase performance, I need to upgrade to hardware that is able to take at least 4 to 6+ GB of RAM, to modern hardware on each of the servers I have to make it go faster?
Not only that it will still be slow, very expensive and an unnecessary waste of money (Given the absolutely huge cloud costs), it shows that it doesn't scale efficiently to save on costs at all. Oh dear.
This is like saying, "Can you please get a new laptop with 16GB RAM to let my hungry electron apps eat the RAM it wants?, 4GB RAM is not enough and literally causes starvation."
EDIT: To downvoters: Oh so the high overhead and heavy resources of a Rails app and upgrading your instances to new hardware and more RAM requirements is justified with the extremely high cloud infrastructure costs then? Explain your reasons if this is the case.
By the way, I don't want to see your gigantic operating costs if you're running Docker & Kubernetes on a multi-instance Rails stack.
> Everything is fast for small n. When n gets large, that's when things start to go sideways. The above graph of an ancient Trash-80 clobbering a semi-modern DEC Alpha is a sobering reminder that the fastest hardware in the world can't save you from bad code.
> "a basic proof of concept"
Ruby only ever has one big ecosystem (web development), whereas Python has expanded into several.
But Ruby isn’t going anywhere, so no need to be sad. It’s still a joyful scripting language, and its community is alive and well :)
However, recently I started a project with Ruby, thanks to language servers. I’m hoping this solves that issue, but it’s too soon to say.
There’s still other issues with the require mechanism, and Ruby in general, and other languages to try, e.g. Elixir and Crystal. I haven’t been sold yet in terms of what Ruby excels at, and those languages are each different in their own right.
The tooling still catches all dependencies and their sources though (via `mix xref ...`)
What do u mean exactly?
The Ruby language server in question: https://solargraph.org/
Like, ... 'move' or 'read', or some other horribly overloaded function that is the one that I need to go and find the specific implementation of because it's busted.
You need more than just Rubymine in many cases.
And no, sometimes it's quite difficult to get the exact configuration required to get that code path to figure out what's wrong.
To GP: there weren’t at the time any other options for a Ruby “smart-editor” AFAIK. However, like I mentioned in my comment, I’m giving Solargraph , a Ruby language server, a try, which is equivalent.
Now of course, there exist other simpler frameworks (a la sinatra), but when your posterchild is a thing like Rails, you can't expect people to not be burnt in the long term and still come back.
If you're interested in front-end performance, having a webpack build pipeline for your frontend assets is quite useful, especially if you want to leverage libraries like react or vue and build interactive reusable components, or leverage existing ones.
Tree shaking, minification, chunking, splitting, etc. will help you deliver a faster initial page load, which is a better overall experience and is also factor in search ranking for your public pages.
Front-end engineering has changed because users expect interactive experiences. Rails has an opinionated way to solve this differently using turbolinks and Rails UJS. A very significant proportion of folks don't want to go that route, enough for it to become the default.
ruby has nothing to offer so it was left behind. maybe possibility to take your old code and ccompile it into C and gain massive performance will put ruby back on map, but i would not count on it. ruby was just a sillicon valley favourite pet that's no longer the case so i would not keep my hopes up for a big return.
I use it all the time and still haven't actually done anything with Rails.
The last thing I wrote in Ruby was a script to help manage my email inbox using imap.
I think Rails really was a very mixed blessing for Ruby - on one hand it brought a lot of people. On the other hand it associated the language with a whole lot of practices that has done long term damage.
Am enjoying the nostalgia quite a bit :)
4 year old Rails is probably fully supported on them.
In practice 99% of the time plain old MRI is fast enough for the things I do. The rest of the time, resorting to RubyInline or a C-module has usually been more than enough.
E.g. the bulk of my code for my masters that involved heavy use of k-nearest neighbour implementations etc. for pre-processing image files for OCR was written in Ruby, with only ~2-3% then replaced with RubyInline C-code to get the speed needed.
I'd take that over Crystal any day, as I don't like the places where Crystal diverges.