4 ms·
Rails doesn't help you form a proper domain model. Or force you to put side-effects in the proper place; it doesn't help with evolving a proper data model, or a
by berkes 6y ago
Rails doesn't help you form a proper domain model. Or force you to put side-effects in the proper place; it doesn't help with evolving a proper data model, or avoid tight coupling in unwanted places, it has hardly any tooling in place to employ design patterns.
On contrary: often it encourages bad practices through "defacto" standard gems, or by making "the wrong choice" easier than "the proper design pattern". A "concern" is a simple way to turn a 800-lines controller into four 300 lines modules that amount to the same ball-of-mud, for example. (Concerns have great use-cases, but most often it is not the solution to your problem). Rails offers things like `try(:foo)` to quickly solve that equivalent of the "null-pointer"- exception, without forcing the developers to dive and in and solve the reason why it is nil, or solve it with some design pattern (adapters, null-pattern etc) either: just keep sprinkling `try()` keeps it rattling along too. Somewhat.
So, yes: lack of proper design and architecture is the real problem behind those "ball-of-mud" rails projects.
But Rails' lack of training-wheels and the ease at which to make the wrong choices, really doesn't help teams aim at proper design and archicture either.
- joelbluminator 6y agoRails has a flat structure, it has no knowledge how big your project will become. For many, many code bases this is good enough. Look at Gitlab, which is quite big. If you need more structure there are many design patterns you can follow and introduce into your codebase.
- pdimitar 6y agoGitLab is also notoriously difficult to deploy by yourself (okay, lately it has been better though) and slow as hell.
- joelbluminator 6y agoI like their UI just fine. Speed, smoothness, never had much of a problem. And the amounts of features they were able to come up with the last few years is pretty impressive.
- pdimitar 6y agoIn terms of features I quite like GitLab as well. I just think it's time they rewrote it in something much faster than Rails. I have literally never used a fast GitLab instance. Anecdotal evidence, I am aware. I'd still venture out to claim this says something about the average speed of your average GitLab installation though. I'm rooting for them. GitHub needs competition.
- joelbluminator 6y agoHmm don't see any rewrite in their cards though...they're pretty much gonna ride this thing with Ruby. If Shopify did it with their monster scale I bet they can as well.
- e12e 6y ago> Rails doesn't help you form a proper domain model. Or force you to put side-effects in the proper place; it doesn't help with evolving a proper data model, or avoid tight coupling in unwanted places, it has hardly any tooling in place to employ design patterns. I think this is only half true. Rails certainly forces very little on you - but has lots of documentation and helping hands pushing you towards tdd - and it has fairly powerful and simple tools to help with data modeling - as long as your data can fit reasonably in the ActiveRecord pattern. More complex subsystems can be split out into rails engines or services. All that said,it is indeed easy, without some discipline, to roll out complected controllers and views. But I don't think it's fair to say that rails the framework via structure or its official guides, encourages that. Quite the opposite. As for "try" (now for a long time largely subsumed by ruby's built in &-operator) - that can be helpful where appropriate, like with handling input,and occasionally with explicitly optional relationships and nullable values. But of course NULLs should normally be avoided, and the database should be leveraged to ensure data integrity. And rails allow you to do that.
- tomc1985 6y agoOn the nulls bit, in a context where nil is a legitimate value, my team's policy is to use the ampersand operator. To be honest this is preferable because it clutters up code the least. I don't think we use a single try() anywhere, even before I used ampersands it was always `blah_blah unless x.nil?` etc etc
- berkes 6y agoThere are legitimate cases for `nil`, but far less than most people allow. What does "user.last_login_at == nil" mean? `NoMethodError `to_human_date` for `nil` in email.erb. "Quick! lets fix that with a `try(:last_login_at, "Never")`: if nil, it means the user never logged in. You now, without proper thought, you introduced a business meaning to a missing value. Adding tight coupling, slowly painting yourself in a corner. How does this translate to "Could you give me a CSV with all users that never logged in"? Maybe you did mean to assign such domain-meaning to "last_login_at == nil", but then it is far better to explicitely do this. E.g. a `NeverLoggedInUser` subclass, a method on the model `never_logged_in?` an explicit flag in the database, or maybe even a special table "inactive_users" that holds these. All depending on domain-meanings, discussions, use-cases and thought. This is always a lot more work than just throwing another `try` at the bug. Rails "rewards" the bad choice, and somewhat opposes the proper solution. Rails makes it easy to prototype and rapidly move forward: those are good features. But often you should, instead, be forced to halt for a second. To push you towards the whiteboard. Being able to throw in a quick `try` here, or a `sort(last_logged_in: :desc)` with another `where.not(last_logged_in: nil)` there, and so on, are a blessing when quickly moving forward. But they will haunt you in the future. Balancing that is hard, regardless of framework, but Rails' features balance towards the "moving fast" a bit too often in my liking. Esp. because it rewards that team-member who "Gets stuff done" by abusing those "quickfixes", while leaving the project with ever more technical debt etc.