3 ms·
A lot of things in Rails are are anti-patterns in large code bases, but pragmatic in small ones. ActiveRecord itself is a prime example: when you start an app,
by dasil003 11y ago
A lot of things in Rails are are anti-patterns in large code bases, but pragmatic in small ones. ActiveRecord itself is a prime example: when you start an app, putting your business logic directly in ActiveRecord objects works pretty well in most cases, but later on as the models proliferate and grow, you realize that some of them contain business logic which is far too complex to warrant being conflated with persistence concerns. The result is difficulty grokking the higher level business logic that crosses database table boundaries, and potentially slow tests because you can't reliably test complex logic without hitting the database. Of course it's easy enough to add a service layer in a Rails app, Ruby is very flexible, but there's no convention for it so there is a high barrier for making this decision since you lose the benefits of shared patterns.
Some might argue this is bad and Rails got it wrong not to anticipate this problem, but I think it's a good decision to avoid incidental complexity for the 95% of Rails apps that will never grow beyond a certain point. In fact this is a significant reason Rails was able to get traction: in 2004 Java had solid, proven solutions to all possible concerns, but the combinatorial complexity of configuring and making them all play together made simple apps take 10x as long to get working. It's smarter to ship fast and then refactor based on real-world feedback than attempt to implement the perfect architecture before you even know if you're designing the right solution.
- solnic 11y agoYou are right with everything you wrote except one thing: ship fast and the refactor is not only often extremely difficult and risky, there are cases where it becomes almost impossible. That's one of the reasons why I've been working on libraries that could provide similar level of convenience and allow you to rapidly prototype something but with a better foundation where things can be refactored more easily.
- dasil003 11y agoSure. There are objectively better and worse abstractions. If you find a much better abstraction it can make all phases better. That said, I think Rails is pretty good, largely thanks to the flexibility of Ruby.
- saneshark 11y agoYou're being overly modest. You should mention your contributions to the ruby community with respect to Ruby Object Mapper as an example. I have not used it in a project, but in any future undertaking I will most certainly give it a look. One of the reasons I've started to look more to Elixir and Ecto as ORM is because issues like immutability come up more and more. In an ideal world we'd have a dynamic client side querying language like GraphQL, a simple application layer that maps REST to CRUD without constraints pushed upon it based on the ORM, and an ORM abstraction that allows for immutability in our models. Concurrency and race conditions are shouldn't be a developers concern when working with higher level framework.