10 ms·
My comment on one of the previous discussions: I don't want to start a flame war here, but I think Rails (and gem ecosystem in general) is a better choice than
by sellingwebsite 7y ago
My comment on one of the previous discussions:
I don't want to start a flame war here, but I think Rails (and gem ecosystem in general) is a better choice than Django, at least for SaaS apps.
These are all my personal opinions, take it with a grain of salt. Having said that, here we go:
* Authentication - it is a pain if you'd like to deviate from the standard Django User model (using username to login instead of an email). I don't like Devise either.
* Asset pipeline, even though it is not updated anymore (sprockets) and partially replaced by the webpacker, is still better in Rails
* Configuration spread across multiple files, by environment, instead of a single config.py file
* Sidekiq has a better API compared to Celery. Also, Celery's default broker is RabbitMQ, not Redis. It is really hard to find managed RabbitMQ hosting, for Redis there are plenty
* Mailer previews, small but quite useful utility
* Better security by default: Rails comes pre-configured with a bunch of security headers[0].
* Testing - Minitest and Capybara is just a joy to work with.
* I prefer ActiveRecord over Django ORM
* Rails isn't afraid to deprecate things and move forward. This isn't the case with Django, which is big on backwards compatibility. I don't like it, since it puts into a disadvantage folks who are starting new projects. Different strokes for different folks, I suppose
I could go on and on, but I remember struggling a lot with Django/Celery when building a SaaS app. I decided to switch to Rails and haven't looked back (Rails has its warts as well). YMMV
[0] https://guides.rubyonrails.org/security.html#default-headers https://guides.rubyonrails.org/security.html#default-headers
EDIT: Added last point about backwards compatibility
- yagodragon 7y agoIs rails really that good? I feel so confused and paralyzed trying to find a modern backend framework. I've almost settled to Python+Django because it enforces good practices,has great tools like Django Rest Framework and Python is a language with huge application field. On the other hand, laravel and rails have so strong communities and feel more modern (for example, integration with front end frameworks). Django just seems left behind. So the question boils down to this: Should I invest my time learning django in 2019?
- sellingwebsite 7y agoça dépend. I am only familiar with Django and Rails, can't comment about Laravel. If you are building a basic CRUD app, definitely stick with Rails. If you are doing some kind of CMS or need machine learning pipeline, go with Python. A warning about Ruby/Rails: some folks have moved on to shinier languages/frameworks and as a result there are lots of unmaintained gems (gems are 3rd party libraries in the Ruby world) out there. For instance, I needed a curl wrapper written in Ruby. Nothing worked for me so I ended up forking Ethon [0]. I am hesitant to send PRs, since I doubt that they will get merged. Now I am maintaining two codebases at once. I will probably rewrite it from scratch at some time. A warning about Python/Django: dependency management is kind of a mess [1]. See linked discussions [2][3][4][5]. [0] https://github.com/typhoeus/ethon https://github.com/typhoeus/ethon [1] https://xkcd.com/1987/ https://xkcd.com/1987/ (Add pipenv and poetry to the mix) [2] https://news.ycombinator.com/item?id=20672436 https://news.ycombinator.com/item?id=20672436 [3] https://news.ycombinator.com/item?id=18612590 https://news.ycombinator.com/item?id=18612590 [4] https://news.ycombinator.com/item?id=17607083 https://news.ycombinator.com/item?id=17607083 [5] https://news.ycombinator.com/item?id=13459740 https://news.ycombinator.com/item?id=13459740
- Scarbutt 7y agoFor instance, I needed a curl wrapper written in Ruby. Nothing worked for me Curious, why didn't something like faraday worked for you?
- sellingwebsite 7y agoFaraday is a wrapper around several libraries, no? I needed more features that these libraries could offer, namely HTTP/2 support, brotli compression, timings for the requests (namelookup time, tls handshake time, connect time, etc..). Faraday and Net:HTTP is fine if you're doing simple HTTP requests.
- onlyrealcuzzo 7y agoRails is really that good. I'm a dinosaur in web development (I think). I've used everything popular for a decent swath of time: Microsoft's MVC, Java Apps Framework at Google, Django, Drupal & Joomla in PHP, Elixir/Phoenix, Express, and Rails. When I first came across Ruby -- and particular Rails -- I loathed it. Ruby's syntax allows you to get pretty creative, and jumping into Rails + Rspec is like jumping into a Perl repo that's been managed by 3 different people over ten years. There's all kind of things that -- because the syntax is so loose -- it's not clear what's going on. It doesn't help (in my opinion) that Ruby's own style guide almost encourages this: dropping the "()" from functions that take no arguments; Eiminating "{}" around certain hashes passed into functions; The "!" marker having a seemingly different meaning in almost every library, etc... When you're new to Rails and Rspec, it's easy to have no idea what's going on. That being said, you can prototype an entire business in a few days Rails. It is that easy. It's incredibly polished. It's opinionated in mostly right ways, and all of its libraries are, too -- which means you don't often find people doing crazy shit (except Devise, everyone is always doing something crazy with Devise). As much as I hated Rspec with a passion, I do feel like it's the best testing frameworks I've ever come across. It lets you be SUPER expressive about what you're testing. I go against the Ruby & Rspec style guides on a few things, but I feel like no other combination let's you write code that's so expressive. And, finally, anything you want to do in Rails has a library built in that does it very well. And unlike in -- say JavaScript for example -- there aren't ten libraries to pick from. There is a clear winner, and I think that's good for the community. Also, almost every major API you can imagine has a Rails Gem so that it plays nicely with the framework. Don't get me wrong, I loved Django and I still think it's a great framework. My love for Python, Elixir, and Kotlin are strong. Ruby & Rails are by no means perfect, but I do feel like it's a very clear winner if you're starting a new web business. The number of companies I've seen flounder because they wanted an App + a website + (obviously) backend business logic... and all of that in one language, in one code base -- it's impressive. I've seen a lot of Rails businesses fail. But despite what people warn about scaling, I've never seen a Rails-based company fail because of Rails. Plenty have flourished -- Shoppify, GitHub, AirBNB, etc... I could go on and on about the advantages WRT hiring, too. Don't even get me started...
- steve_adams_86 7y agoI recently got up to speed with a rails app remarkably quickly and I agree with all of these points. I found testing wasn't really a joy, but it was less painful than any experience I've had in the python or PHP world. Mailer previews are actually very cool, too. It's not a game changer but I liked having it and it came in handy. ActiveRecord was also surprisingly slick. I'd previously mostly used Doctrine and over the years I've mostly come to dislike it. AR was fine though and had some features I liked quite a bit. Scopes are really neat. Like any ORM though there are plenty of double edged swords all over. I'm actually keen to work with Ruby more since working on that project. Rails is really nice, even if it's a lot different from how I'm used to working. It felt very productive.
- m_ke 7y ago1. Changing the base user model is not that hard if you're starting a new project. It took us a few hours to make that change. 2. Nothing is stopping you from using multiple files for config. We use a config module with a separate file for DB, caching, DRF and etc. 3. Testing with pytest is pretty nice too. Django rest framework is what makes Django great these days.
- sellingwebsite 7y agoYou have just proven my points. Sure you could do it yourself, but defaults matter. A lot.
- m_ke 7y agoThe defaults in Django work fine for most people. I've used rails before and it's a great framework but python has a much better ecosystem, especially if you're doing anything machine learning ralated.
- tidepod12 7y agoI don't see how your points were proven. The 'defaults' you're talking about take a grand total of ~10 minutes tops to change, and actually can come by 'default' if you use one of the available Django templates that are popular. Your complaints are valid from a subjective perspective, but if your bar for something being "a pain" is really "took longer than 10 minutes", I can't imagine how you function as a software engineer as even in Rails there are many things that will take longer to do.
- sellingwebsite 7y agoHow about "I was struggling for days with Django which lead to a minor burn-out and as a result I lost several weeks of my time"? That's when I decided to pick up Rails tutorial and it was probably one of the best tech-related decisions I made in my businesses. I shouldn't use cookiecutter templates, plugins, scripts to make working with the software tolerable. It should just work and get out of my way. Well, at least when doing a greenfield development. Take a look: https://rubyonrails.org/doctrine/ https://rubyonrails.org/doctrine/
- yowlingcat 7y agoI can't argue about your preferences here, but these seem to be subjective preferences or complaints about warts. In terms of feature and ecosystem surface, there is one area where I think Django is a clear winner: Django Admin. It is a very mature part of the framework and there is a large ecosystem around it. Compared to how useful that is for standing up an MVP SaaS (especially in anything remotely enterprisey), I would find it difficult to consider Rails if I ever envisioned needing admin. For what it's worth though, I think that Django and Rails are both exceptional choices and in terms of ergonomics, best in class. I wouldn't have complaints about the framework to coming into a project using either one.
- tyre 7y agoHaving never used Django Admin, how would you compare to Rails Admin and Active Admin?
- freehunter 7y agoThe only comparison I can do is that Django Admin is built-in out of the box, so I use it on every Django project. Rails/Active Admin is not built-in out of the box so I've never used it and always built my own admin page. It's super weird because Rails is known for convention over configuration and includes default packages for basically everything you might need EXCEPT auth and admin. Meanwhile Django removes a lot of the magic of Rails and lets you do it yourself, except for bundling auth and admin into the core product.
- BOBOTWINSTON 7y agoI used ActiveAdmin a lot when I started and it always gave me a headache. From what I have seen of Django Admin (admittedly not a lot) it looks very similar? I have found that at least for my users, admin type functionality and views generally require a lot of custom work that is not easily turned into convention. About 4 years ago I stopped using Active Admin completely and just started using Ransack + Kaminari gems on their own. I have been a much happier with the way that pattern has worked out.
- tyre 7y agoActiveRecord is the best ORM I've ever used, in any language, and I don't know of an engineer I've worked with who disagrees, regardless of their preferred stack. Using `merge` on two queries still blows my mind. I've been using SQLAlchemy lately and it's a daily reminder of just how many things AR got right. Rails has its downsides (helloooooo memory usage!) but for getting up and running fast and having a full toolkit available to get the basics done, it's a pretty amazing project.
- cortesoft 7y agoIn fairness I haven't used ActiveRecord in a few years, but I really love the Sequel ORM for ruby over my previous experience with ActiveRecord. I feel like ActiveRecord can be a bit too magic for some of the more complicated things I have to do with my models.
- tsotpsstt 7y ago+1 for Sequel. I've decided to try Sequel instead of AR for new project 3 years ago. Never looked back, feels like a breath of fresh air. Hope it will gain more recognition in the Ruby community.
- pg_bot 7y agoI used to hold this opinion until I started using elixir's ecto library. However, I still do hold ActiveRecord in high regard.
- tyre 7y agoI love ecto as well. I love pure SQL and interfacing closer to raw data. Phoenix/Ecto is where I'd gravitate starting a new project (we used it in production at our startup) for many reasons including the simplicity of deployments. For people getting started with engineering, AR is a nice wrapping/mapping of SQL => object oriented models. There's a mix of productivity, approachability, and feature set that puts AR ahead, for me, as a general use ORM. I would agree, though, with a strong and experienced engineering team Ecto and Elixir are quite nice.
- belak 7y agoFor me, I prefer Django, but I haven't used Rails in a number of years. In general I prefer Python over Ruby because it's more explicit and less magic, but Ruby definitely has its conveniences. That being said, I am not a Ruby developer, I am a Python developer, so I'll try to address these points as best I can from the other side of the equation. * Authentication - this is fairly simple to address. It's a fairly easy-to-use pluggable backend. It's not very hard to write a system to replace the default which would let you log in using other credentials. Also, a few years ago you couldn't replace the default User model - that has since been changed. * Asset pipeline - fair point, but I prefer to keep my assets separate from the backend if possible - my current work project has a backend API in django with a separate frontend repo with all the JS/CSS * Configuration - the best solution for this I've found is django-environ[0]. Alternatively, the built-in `DJANGO_SETTINGS_FILE` environment variable lets you specify a different base config file. * Sidekiq/Celery - The API, I'll give you, however it's fairly easy to configure Celery to use Redis * Mailer previews - I've used mailhog[1] before. This gives you a local mailbox to test with and will be closer to your final configuration anyway. * Better security - possibly by default, but I haven't had any issues with django-rest-framework in the past * Testing - pytest with pytest-django is also great to work with. * Django ORM vs ActiveRecord - I don't have a ton of experience with ActiveRecord but I like the Django ORM. There's also SQLAlchemy, but it's a bit odd to rip that out of django if you don't need to. I like Django because it's solid out of the box, but still provides a way to extend the core to be as flexible as you want. I assume it's possible to do this with Rails, but that's not my area of expertise. I do appreciate you outlining things you like better as opposed to just saying "Django is terrible". I'll definitely have to try Rails again and see what I think of it now. [0] https://github.com/joke2k/django-environ https://github.com/joke2k/django-environ [1] https://github.com/mailhog/MailHog https://github.com/mailhog/MailHog
- correlator 7y agoRails is a business tool. It allows developers to move quickly to build and iterate rapidly on the business vision. This means a lot of interesting engineering work and optimizations are out of your hands. Some people think that's a bad thing, I think it's a great thing. Depends on your goals.
- myalphabet 7y agoWhy does every thread about Rails on HN devolve into a thread bashing Django? Do Rails users have some kind of "little brother complex" compared to Django? Every Django thread on HN usually involves a healthy amount of discussion about the pros/cons of Django, and it's really helpful. You would expect that Rails threads have a discussion about the pros/cons of Rails, right? Except instead, every Rails thread also turns into a discussion about the pros/cons of Django. If Rails is so good then why do its users feel they have to constantly defend itself against non-existent attackers?
- sellingwebsite 7y agoBecause I've got burnt by Django in the past. If you do some search on the HN and elsewhere on the difference between two, the common answer that you'll find is that they are similar and it doesn't matter which one do you pick (given that you are not proficient with any of them). I don't agree with that premise and decided to make a case here. So if you are ever in a position to pick between Django and Rails for CRUD-y SaaS app, go with Rails. You can't go wrong with that.
- arshbot 7y agoUnderstandable sure, but why bring up Django on a post about upgrading to Rails 6.0 a week after 6.0 was released?
- sellingwebsite 7y agoBecause I too followed the common advice and started with Django (I only knew Python back then). Well, I hated it and got burnt out as a result. So, despite the conventional wisdom, I decided to change my stack from Django/Python/Celery to Rails/Ruby/Sidekiq and I am very glad I made the leap. I have seen both sides of it, that's why I decided to vent it out. P.S. Don't get me wrong, I have tons of respect for people doing open source and don't want to badmouth Django folks. But in my limited experience, it just wasn't a great experience.
- 7y ago
- drspacemonkey 7y ago>I don't like Devise either I've got my complaints about Devise, but I'll take those pains any day of the week over the alternative nightmare of "built in-house" authentication. At this point, if somebody doesn't want to use Devise in a project I'm working on, they better have a _really_ good explanation. To me, it's like suggesting setting the building on fire.
- sellingwebsite 7y agoCustom built auth isn't as scary as you make it to be. I have done it myself and would do it in the future. You just have to be cognizant of what you're doing (i.e. simply copying Hartl's or Railscasts' tutorial won't suffice; see session fixation attacks). If I were to bring in 3rd party gem for auth, I'd have gone with Sorcery rather than Devise.
- dymk 7y ago> Custom built auth isn't as scary as you make it to be > You just have to be cognizant of what you're doing These two ideas are incompatible with each other.
- headmelted 7y agoI would have phrased it differently, but I see the parent's point. You don't roll your own security. You just don't do it. There are far too many variables that you can screw up, and anything you come up with isn't realistically going to go through nearly as much battle-testing as a ready-made solution (either upfront or on an ongoing basis). > Custom built auth isn't as scary as you make it to be Custom-built auth should be scary. Anyone who's worked on the security story for a popular framework will tell you that. If you're not scared by it I'd have to assume you're either not seeing large swathes of the problem space or you're a genius.
- ratww 7y agoI'd argue that Auth itself isn't hard per se, but it involves hard things that you shouldn't roll your own, notably cryptography and session handling. But those are things that people normally delegate to either libraries (crypto) or the framework itself (session handling). Of course, there's lots of places one can screw up, such as sending non-expirable password reset tokens, revealing private information and membership status via F2A/reset tokens. But those are the kinds of screw-ups that can happen in other parts of the website too. That said, Devise is one of the few things that I don't completely dislike about Rails.
- diegojromero 7y agoCould you expand on why do you prefer ActiveRecord over Django ORM? When I started with Rails I was so frustrated with ActiveRecord that I develop some of the Django QuerySet API as a gem[0]. [0] https://github.com/diegojromerolopez/babik https://github.com/diegojromerolopez/babik
- ljm 7y agoRails gets background processing emphatically wrong. Rails does a lot of things right, but ActiveJob and everything built upon it (including the abuse of Redis) is a travesty. The entire concept of serialising code and re-evaluating it (which is what these libraries do) is a joke. Your job payload should be pure data but Rails ensures that it is code. And you should builds the workers that consume it.
- steveklabnik 7y agoThis comment would be much better if you explained why you think so, even at a high level.
- dymk 7y agoJob payloads are certainly not code; they're exposed to the developer as basically blobs of JSON, and the code lives in a "job handler" which is certainly itself not serialized.
- gwright 7y ago> Your job payload should be pure data but Rails ensures that it is code. Doesn't sound right to me. ActiveJob just serializes the arguments to the job. The job runners spins up the rails environment (i.e. the code) and deserialize the arguments before executing the job. There is no code serialization as far as I can tell.
- deleted 7y ago[deleted]
- tptacek 7y agoNo, I don't think many application security people would agree with you that Rails is more secure out of the box or in common configurations than Django. I don't think it matters much; the differences are probably marginal. (I've shipped Rails applications and would probably not myself ever pick Django for a new project. Obviously, I do more security work than application development work).
- conroy 7y agoIf you wanted to avoid a flame war, you wouldn't have posted in the first place. Why bring up Django when the linked post is about upgrading a Rails code base to 6.0?
- cdcarter 7y agoFor what it’s worth/to prevent too much FUD about something as important as secure by default, Django has fantastic security header defaults out of the box too. https://docs.djangoproject.com/en/2.2/ref/middleware/#module-django.middleware.security https://docs.djangoproject.com/en/2.2/ref/middleware/#module...
- mushufasa 7y ago> * Authentication - it is a pain if you'd like to deviate from the standard Django User model (using username to login instead of an email). It's not so hard, you just define a custom user class -- plenty of SO snippets if you're lazy. Though I agree that it would be better if common user schemes like email login were supported out of the box. >* Better security by default: Rails comes pre-configured with a bunch of security headers[0]. Django has security headers also https://docs.djangoproject.com/en/2.2/topics/security/ https://docs.djangoproject.com/en/2.2/topics/security/ > * Sidekiq has a better API compared to Celery. Also, Celery's default broker is RabbitMQ, not Redis. It is really hard to find managed RabbitMQ hosting, for Redis there are plenty There are several on Heroku, including with free plans. https://elements.heroku.com/addons/cloudamqp https://elements.heroku.com/addons/cloudamqp . I agree that Celery has a bit of a learning curve (e.g. heartbeat, concurrency, etc.). The project is improving, and python overall is getting better at async. > Django, which is big on backwards compatibility. Version 2.0 breaks code from 1.11, which happened in 2017. > I decided to switch to Rails and haven't looked back Maybe Django improved since you last looked, and could merit another try :). > I don't want to start a flame war Nor do I. Both cake and pie are good. The ability to weave in the rest of the python ecosystem (e.g. pandas, keras) makes Django attractive to me for many projects.
- malloryerik 7y agoWhat's the real-time / reactive story looking like for Rails these days? Should one choose Rails for new real-time apps?
- sprite 7y agoThis might be outdated but should give you some idea at least https://dockyard.com/blog/2016/08/09/phoenix-channels-vs-rails-action-cable https://dockyard.com/blog/2016/08/09/phoenix-channels-vs-rai...
- SiliconAlley 7y agoI have worked extensively in both frameworks and would add to this: * Django has comparatively limited I18n and localization faculties compared to Rails (with Django’s i18n built atop gettext, which I always found kind of brittle with .po files/string-based keys) * No intelligent/efficient class reloading in development. The whole development server just restarts when you make changes * No reloader for the shell (horrible for developer ergonomics - you can't just type "reload!", you have to restart the shell to pull in any change) * Caching faculties in Django are much more limited - no template digests (to make template fragment caching much more robust) * ActiveSupport has also always been a god-send for productivity. It may seem small but things like “Array#to_sentence” and the time functions (i.e. 1.day.ago) are incredibly useful. * No default assumption of multiple environments (no default development/testing/production configuration files, environment detection, etc). This is pretty ridiculous for a web application framework. * No built in credential encryption (makes keeping a team in-sync with keys for integrations a comparative pain) * Dependency management is much more challenging in Python. The de-facto virtualenv + requirements.txt combo is lossy (no dependency graph) and awkward compared to bundler. There are other solutions here but something so foundational shouldn’t be so hard. Django was the first web application framework I learned and I still work with it professionally from time to time (as recently as ~2 months ago). I am just a bit stunned by how much it has fallen behind in terms of its broad state of maturity, community/ecosystem, productivity, etc.
- batiste 7y agoFor once a fair criticism of Django by someone who seems to know the framework well. I don't quite share the same experience with i18n though. I always found Django statical code analysis to extract translation keys to be superior in many ways to other translation systems. It is giving useful context that are stored in the PO files and good translation tools use them. I also never had any issue with string based keys. You can chose an english based key or an abstract whatever you prefer. Some of the annoyance you mentioned, that I agree completely, are more of a language issue like: reloader, or dependency management. For multiple environments there is a very simple pattern you can put in place using an environment variable and conditional imports. something like: from settings.base import * if env == 'prod': from settings.prod import *