Join devRant
Do all the things like
++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatar
Sign Up
Pipeless API
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple API
Learn More
Search - "active record"
-
Hey everyone,
First off, a Merry Christmas to everyone who celebrates, happy holidays to everyone, and happy almost-new-year!
Tim and I are very happy with the year devRant has had, and thinking back, there are a lot of 2017 highlights to recap. Here are just a few of the ones that come to mind (this list is not exhaustive and I'm definitley forgetting stuff!):
- We introduced the devRant supporter program (devRant++)! (https://devrant.com/rants/638594/...). Thank you so much to everyone who has embraced devRant++! This program has helped us significantly and it's made it possible for us to mantain our current infrustructure and not have to cut down on servers/sacrifice app performance and stability.
- We added avatar pets (https://devrant.com/rants/455860/...)
- We finally got the domain devrant.com thanks to @wiardvanrij (https://devrant.com/rants/938509/...)
- The first international devRant meetup (Dutch) with organized by @linuxxx and was a huge success (https://devrant.com/rants/937319/... + https://devrant.com/rants/935713/...)
- We reached 50,000 downloads on Android (https://devrant.com/rants/728421/...)
- We introduced notif tabs (https://devrant.com/rants/1037456/...), which make it easy to filter your in-app notifications by type
- @AlexDeLarge became the first devRant user to hit 50,000++ (https://devrant.com/rants/885432/...), and @linuxxx became the first to hit 75,000++
- We made an April Fools joke that got a lot of people mad at us and hopefully got some laughs too (https://devrant.com/rants/506740/...)
- We launched devDucks!! (https://devducks.com)
- We got rid of the drawer menu in our mobile apps and switched to a tab layout
- We added the ability to subscribe to any user's rants (https://devrant.com/rants/538170/...)
- Introduced the post type selector (https://devrant.com/rants/850978/...) (which will be used for filtering - more details below)
- Started a bug/feature tracker GitHub repo (https://github.com/devRant/devRant)
- We did our first ever live stream (https://youtube.com/watch/...)
- Added an awesome all-black theme (devRant++) (https://devrant.com/rants/850978/...)
- We created an "active discussions" screen within the app so you can easily find rants with booming discussions!
- Thanks to the suggestion of many community members, we added "scroll to bottom" functionality to rants with long comment threads to make those rants more usable
- We improved our app stability and set our personal record for uptime, and we also cut request times in half with some database cluster upgrades
- Awesome new community projects: https://devrant.com/projects (more will be added to the list soon, sorry for the delay!)
- A new landing page for web (https://devrant.com), that was the first phase of our web overhaul coming soon (see below)
Even after all of this stuff, Tim and I both know there is a ton of work to do going forward and we want to continue to make devRant as good as it can be. We rely on your feedback to make that happen and we encourage everyone to keep submitting and discussing ideas in the bug/feature tracker (https://github.com/devRant/devRant).
We only have a little bit of the roadmap right now, but here's some things 2018 will bring:
- A brand new devRant web app: we've heard the feedback loud and clear. This is our top priority right now, and we're happy to say the completely redesigned/overhauled devRant web experience is almost done and will be released in early 2018. We think everyone will really like it.
- Functionality to filter rants by type: this feature was always planned since we introduced notif types, and it will soon be implemented. The notif type filter will allow you to select the types of rants you want to see for any of the sorting methods.
- App stability and usability: we want to dedicate a little time to making sure we don't forget to fix some long-standing bugs with our iOS/Android apps. This includes UI issues, push notification problems on Android, any many other small but annoying problems. We know the stability and usability of devRant is very important to the community, so it's important for us to give it the attention it deserves.
- Improved profiles/avatars: we can't reveal a ton here yet, but we've got some pretty cool ideas that we think everyone will enjoy.
- Private messaging: we think a PM system can add a lot to the app and make it much more intuitive to reach out to people privately. However, Tim and I believe in only launching carefully developed features, so rest assured that a lot of thought will be going into the system to maximize privacy, provide settings that make it easy to turn off, and provide security features that make it very difficult for abuse to take place. We're also open to any ideas here, so just let us know what you might be thinking.
There will be many more additions, but those are just a few we have in mind right now.
We've had a great year, and we really can't thank every member of the devRant community enough. We've always gotten amazingly positive feedback from the community, and we really do appreciate it. One of the most awesome things is when some compliments the kindness of the devRant community itself, which we hear a lot. It really is such a welcoming community and we love seeing devs of all kind and geographic locations welcomed with open arms.
2018 will be an important year for devRant as we continue to grow and we will need to continue the momentum. We think the ideas we have right now and the ones that will come from community feedback going forward will allow us to make this a big year and continue to improve the devRant community.
Thanks everyone, and thanks for your amazing contributions to the devRant community!
Looking forward to 2018,
- David and Tim48 -
To all the people giving advice in my previous rant (https://devrant.com/rants/1627035/...), thanks!
I've spent a weekend running high and naked through the forest, and decided to quit my job.
Fuck PHP. Fuck Laravel. Fuck hipster startup companies. Rasmus Lerdorf, Taylor Otwell and my CEO can all go suck each other's cocks in a sloppy mess of saliva, cum and type errors.
I'm so sick of spinach smoothies and weakly typed languages. All active record ORMs are retarded, VueJS is worse than JQuery, Fatal error: Call to a member function iHatePHP() on null. WHY DOES PHP EVEN HAVE METAPROGAMMING METHODS, WHY THE FUCK DOES LARAVEL CHOOSE EASY OVER SAFE.
I'm going to use my heavily abused Macbook to surf out of this mess, on a collapsing wave of unresolved bugs.
On to the next PHP/Laravel job at a hipster startup!26 -
Every day.
I am a PHP developer.
Yeah, "another PHP is awful" rant... no, not really.
It's just unsuitable for some ambitious projects, just like Ruby and Python are.
First of all, DO NOT EVER use Laravel for large enterprise applications. The same goes for RoR, Django, and other ActiveRecord MVCs.
They are all neat frameworks for writing a todo app, as a better-than-wordpress flexible blogging solution, even as a custom webshop.
Beyond 50k daily users, Active Record becomes hell due to it's lazy fat querying habits. At more than a million users... *depressed sigh*.
PHP is also completely unsuitable for projects beyond 5M lines of code in my opinion. At more than 25M lines... *another depressed sigh*.
You can let your devs read Clean Code and books about architecture patterns, you can teach them about SOLID & DRY, you can write thousands of tests... it doesn't matter.
PHP is scaffolding, it's made of bamboo and rope. It's not brick or concrete. You can build quickly, but it only scales up to a certain point before it breaks in multiple places.
Eventually you run into patterns where even 100% test coverage still doesn't guarantee shit, because the real-life edge cases are just too complex and numerous.
When you're working on a multi-party invoicing system with adapters for various tax codes, or an availability/planning system working across timezones, or systems which implement geographical routefinding coupled to traffic, event & weather prediction...
PHP, Python, Ruby, etc are just missing types.
Every day I run into bugs which could have been prevented if you could use ADTs in a generic way in PHP. PHP7 has pretty good typehints, and they prevent a lot of messy behavior, but they aren't composable. There is no way to tell PHP "this method accepts a Collection of Users", or "this methods returns maybe either an Apple or a Pear, and I want to force the caller to handle both Apple/Pear and null".
Well, you could do that, but it requires a lot of custom classes and trickery, and you have to rewrite the same logic if you want to typehint a "Collection of Departments" instead of "Collection of Users" -- i.e., it's not composable.
Probably the biggest issue is that languages with a (mostly) structural type system (Haskell, Rust, even C#/JVM languages to some degree, etc) are much slower to develop in for the "startup" era of a project, so you grab a weak, quick prototyping language to get started.
Then, when you reach a more grown up phase, you wish you had a better type system at your disposal...28 -
Laravel is the worst framework ever.
Everything has to be made convenient and easy. That sounds amazing, because developers want to save time, worry less about boilerplate code, right? No more constructors, no more dependency injection, fuck all the tedious OOP shit... RIGHT?
It does one thing well: Make PHP syntax uniform and concise through easily integrated libraries such as Collection and Carbon. But those are actually not really part of the framework... just commonly integrated and associated with Laravel.
The framework itself is completely derailed: You can define code in a callback in the routes file. You can define a controller in the routes file. You can define middleware as a parameter to the route, as a fluent method to the route, you can stack them up in a service provider. Validators can be made in controllers, Request objects, service providers, etc. You can send mail inline, through Mailable objects, through Notification objects, etc.
Everything is macroable, injectable, and definable in a million different places. Ultimate freedom!
Guess what happens when you give 50 developers of various seniority a swiss army knife?
One hammers in a screw with a nail file, the other clips the head from the screw using scissors, and you end up with an unworkable mess and blunt tools.
And don't get me started about Eloquent, the Active Record ORM. It's cute for the simple blog/article/author/comment queries, but starts choking when you want more selective and performant queries or more complex aggregates, and provides such an opaque apple-esque interface which lets people think everything is OK, when in reality it's forcing the SQL server to slowly commit suicide.50 -
I wrote a database migration to add a column to a table and populated that column upon record creation.
But the code is so freaking convoluted that it took me four days of clawing my eyes out to manage this.
BUT IT'S FINALLY DONE.
FREAKING YAY.
Why so long, you ask? Just how convoluted could this possibly be? Follow my lead ~
There's an API to create a gift. (Possibly more; I have no bloody clue.)
I needed the mobile dev contractor to tell me which APIs he uses because there are lots of unused ones, and no reasoning to their naming, nor comments telling me what they do.
This API takes the supplied gift params, cherry-picks a few bits of useful data out (by passing both hashes by reference to several methods), replaces a couple of them with lookups / class instances (more pass-by-reference nonsense). After all of this, it logs the resulting (and very different) mess, and happily declares it the original supplied params. Utterly useless for basically everything, and so very wrong.
It then uses this data to call GiftSale#create, which returns an instance of GiftSale (that's actually a Gift; more on that soon).
GiftSale inherits from Gift, and redefines three of its methods.
GiftSale#create performs a lot of validations / data massaging, some by reference, some not. It uses `super` to call Gift#create which actually maps to the constructor Gift#initialize.
Gift#initialize calls Gift#pre_init (passing the data by reference again), which does nothing and returns null. But remember: GiftSale inherits from Gift, meaning GiftSale#pre_init supersedes Gift#pre_init, so that one is called instead. GiftSale#pre_init returns a Stripe charge object upon success, or a Gift (and a log entry containing '500 Internal') upon failure. But this is irrelevant because the return value is never actually used. Pass by reference, remember? I didn't.
We're now back at Gift#initialize, Rails finally creates a Gift object using the args modified [mostly] in-place by all of the above.
Another step back and we're at GiftSale#create again. This method returns either the shiny new Gift object or an error string (???), and the API logic branches on its type. For further confusion: not all of the method's returns are explicit, and those implicit return values are nested three levels deep. (In Ruby, a method will return the last executed line's return value automatically, allowing e.g. `def add(a,b); a+b; end`)
So, to summarize: GiftSale#create jumps back and forth between Gift five times before finally creating a Gift instance, and each jump further modifies the supplied params in-place.
Also. There are no rescue/catch blocks, meaning any issue with any of the above results in a 500. (A real 500, not a fake 500 like last time. A real 500, with tragic consequences.)
If you're having trouble following the above... yep! That's why it took FOUR FREAKING DAYS! I had no tests, no documentation, no already-built way of testing the API, and no idea what data to send it. especially considering it requires data from Stripe. It also requires an active session token + user data, and I likewise had no login API tests, documentation, logging, no idea how to create a user ... fucking hell, it's a mess.)
Also, and quite confusingly:
There's a class for GiftSale, but there's no table for it.
Gift and GiftSale are completely interchangeable except for their #create methods.
So, why does GiftSale exist?
I have no bloody idea.
All it seems to do is make everything far more complicated than it needs to be.
Anyway. My total commit?
Six lines.
IN FOUR FUCKING DAYS!
AHSKJGHALSKHGLKAHDSGJKASGH.7 -
> TeamLeader1: I just discovered SQL is actually super fast! The low responsiveness I've experienced comes from our ORM!
> IHateForALiving: well of course SQL is blazingly fast. SQL has been refined by the best engineers in the world for the past 50 years, its performances are unparalleled for everything you could possibly need, unless you want to scale REALLY big. Sequelize, instead, is an Active Record ORM, so it's bound to struggle with huge amount of data, because every single row will get attached a significant amount of black magic to make sure everything syncs correctly. Why is that?
> TeamLeader1: I have a problem with this frontend component, it doesn't allow pagination. I tried downloading the whole DB to bypass that, but the ORM is slow... so I will bypass the ORM and download the whole table with a raw query. Look at that! It works like a charm, it's super duper fast!'
This mf is downloading some 35 thousand rows every time some user loads a page because he doesn't know how to paginate the fucking table with Angular, there's no way these people are real.12 -
STUPID RAILS!
WHY CAN'T YOU JUST BUILD THE BLOODY QUERY WITHOUT DOING FANCY UNNECESSARY SUBQUERY SHIT?!
OR PUT THE LIMIT WHERE IT MAKES SENSE AND DOESN'T CAUSE MYSQL TO TELL YOU TO FUCK OFF?
WHY WHY WHY WHY WHY
THIS ISN'T HARD18 -
Rails console:
> `ModelOne.joins("ModelTwo")`
# => ActiveRecord::StatementInvalid (Mysql2::Error: Unknown table 'database_name.model_ones')
MariaDB:
> `select count(*) from database_name.model_ones`
# => 13274641
It's right there, ffs4 -
Look at that. The very fucking smart colleague spent 40 days implementing a repository pattern (WHEN WE'RE USING AN ACTIVE RECORD ORM), breaking stuff left and right. Does he use that fucking pattern at the very least?
Of course he doesn't. And along the way he's making sure to create conflicts with the stuff he broke (and I'm fixing). By the time I fix the merge conflicts of one commit, he pushed 6 of them.9 -
Sorry I haven't been as active lately, however this is one of the better prompts, so I feel I should have it in my track record. Beware, it's a long one...
Let's trace the roots: My uncle was building desktops and he told my dad he'd build him one if my dad paid him for the components. These days I know builds aren't rocket science, but back then my parents didn't do their research. So my dad paid him.
Give or take some time, and most of the parts are complete. He underestimated the prices of a few things and had to ask for $200 more to complete the build. This...caused my dad to explode.
Later, I heard my dad ranting to my stepmom in January 2017 about how the last convo he had with his brother was a "Fuck-you conversation" - it was the last because my uncle had died in 2003.
Flash forward to March 2017. My mom and I are sitting in a Fazoli's, a nice sunset out of the full-length windows. I had to probe. HAD TO.
"You promise you won't tell your dad I told you this?" she asked.
"You know Kellie and I can't stand to be around him." I replied.
As the story goes, that last "Fuck-you conversation"? Over a fucking measly $200. Yup, the last conversation between my dad and his brother to ever happen was a shouting match over a relatively short amount of money. I wish I could say my dad had remorse, but he doesn't. He still talks shit. He's also technologically illiterate, so I doubt there was a way his brother was going to be able to reason with him.
In late 2003, my uncle, who had been a smoker, passed away due to cardiac arrest. The build was still not finished. This was one of the OTHER things that I have mixed feelings about.
After my uncle passed, my aunt paid someone to finish the build and get it shipped to my dad. We'll get back to why I feel this is fucked up, stay tuned...
---------
It's Spring 2004. I'm in the last half of what I think is Kindergarten or some shit...too lazy to do the math. Anyway, my dad announces we have a family computer - however, I couldn't read yet. That didn't stop the waste of oxygen that is my father from going in the Windows XP screensavers and putting text in that said "GAGE MORGAN WILL NOT TOUCH THIS COMPUTER." He's such a fuckin' dick, now AND back then.
My mom had an issue with this. I don't know why, but she did. Later, I was slowly taught how to use the mouse, under heavy supervision. Then I went to my grandma's house. She taught me one very specific thing on her old Win98 (386, maybe? IDK my old hw shit man), and because I know you guys are gonna love this one:
"The blue "e" opens up your games!"
The blue "e" does not open up your games, it opens something that can lead to your games.
I went home and tried this...without permission. My dad came down and discovered my lollygagging on the homepage - this is fucking weird. It was before Nextel, IIRC, so Sprint's logo was red still. Yes, we had broadband from Sprint. I don't know what saga led to that going the way of the dodo, but...
Back on track, I literally got my pants pulled down and had my bare bottom beat. He was gonna drag my ass upstairs and lock me in my room, but before he could, he accidentally slammed MY FUCKING RIGHT TEMPLE into the corner of a hardwood table at the bottom of the staircase.
The wailing that resulted probably was different than the previous form, which is probably what got my mom involved. My dad had a way of going too far, and in retrospect I'm more terrified now of what could've happened than I was then.
Later, I was given access to games in the form of my own account and bookmarks bar. That wasn't the end of the madness/drama from my use of that machine, but it was the earliest form.
Ever since Kindergarten, that one fateful day, I've been defying any/all imposed limitations on tech set on me by my parents...well, not anymore, but literally grades K-12. I'm living on my own, aka "adulting" now. It sucks more than you think, man.
---------
Let's tie this up before I reach the limit. I said I thought it was fucked up when my aunt paid to have the build finished and shipped to us after my uncle's death.
Yes, my aunt's intervention led to me ultimately majoring in computer science.
That doesn't change the fact that she shouldn't have done it.
My dad was an asshole to her husband, who passed. She is ultimately too caring. I don't think my jackass father should've been able to get by with that, he didn't deserve the freebie. Someone else should've told him his brother did in fact need that $200.
I haven't seen her IRL since the funeral when my grandpa passed in 2005. 2006 spelled the end of my parents' marriage.
Hope you guys enjoyed this - it's only a small segment of how I got to where I am now - tiny, actually.2 -
TLDR;
I remissness about Yahoo site builder and talk about finding the record of the Google search that changed my life a long time ago and I think it's fucking great.
Earlier I re-installed google chrome but unlike every other time, this time I forgot to turn off the auto-sync feature. I only realized this when I opened gmail and it pre-populated my login info with the info of my very first, long forgotten gmail account.
So naturally I went exploring... after going through the mails I decided to check out the actual Google account to see if there was anything of interest there and lo and behold I found around 7 years of browsing history that I had no idea Google stored at the time.
As scary as it was to see I'm kinda glad about it now because aside from finding out that I was going through an Asian porn phase in 2008 I also found the one Google search record that changed my life.
It was a search to download Yahoo site builder followed by a bunch more on how to use it.
I had stumbled across a random article about it and it caught my eye because I needed a website for the grocery store I was a manager of back then.
Thankfully it was a fucking horrible WYSIWYG editor. I recall it acting almost identical to Word at the time - I would save and back up my site constantly because moving something 1px would fuck the layout up and burn everything to the ground, cntrl+z would try and do something, reversing only my last action while leaving the rest of the site in tatters and I didn't have the skills to understand or fix it...
Ultimately my frustration led me learn a bit of html & css and a week or so later It became apparent it would be easier to scratch code the damn thing so I uninstalled Yahoo site builder and started all over again.
Learning & building that site in notepad ignited my passion for coding and less than a year later I left my shitty dead end job to join a brand new tech company created with the help of a like minded investor officially employed as a developer. Let help you understand just how big this achievement was for me - I had been trying to find a job, ANY job in I.T even at a call center level without success for 6 years because I dropped out of school.
In 6 years as an active job seeker I only received one phone call about a job opportunity which ended very quickly once they realised they had misread my CV. In all those years I never even got a single job interview.
After that I spent the next 3 years rolling out and improving the cloud based loyalty card system I had written for my store out on a national scale and the rest is history. Since then I have never been judged by a crappy piece of paper, hated my job or struggled to find a new one.
What a beautiful search result that was to find.
I dedicate this rant to Yahoo, with my sincere gratitude for making a shitty WYSIWYG editor that was so bad it pissed me off enough to make me actually learn something.2 -
Me: You decided some records in system A should be obsolete, but the records are tied to active user accounts on the website. Now, I have users emailing and asking why their profile’s last name field says “shell record - do not use.”
Stakeholder: Oh…can’t you stop those profiles from loading? Or redirect the users to the right record in system A? In system A, we set up a relationship between the shell record and the active one.
Me: 😵 Um, no and no. If I stop a user’s profile from on the website, that’s just going to cause more confusion. And the only way to identify those shell record is to look at the last name field, a text field, for that shell record wording. Also, the website uses an API to query data from system A by user id. Whatever record relationship you established isn’t reflected in the vendor’s API. The website can’t get the right record from system A if it doesn’t have the right user id.7 -
Am I the only one who hates it with his guts that most Active Record implementations infer fields from the db?
Which motherf*cker thought it'd be fun to imagine the model through several migrations, or to imagine the data types in the languague itself when looking at the database?
Let me write the model and infer the f*cking changes to create migrations, not the other way around.