loading...

Rails: The Struggle Is Real

swlkr profile image Sean Walker Updated on ・3 min read

I don’t know how many hours I’ve lost to searching for what should be the easiest thing but instead I wind up scratching my head because I’m forced to do it a crazy complicated way because some danish dude thought it was a good idea. Don’t get it twisted yo, rails has some positive things going for it, but making sense to me is not one of them. Let me give you some concrete examples of some WTF moments I’ve dealt with repeatedly.

Custom form builder helpers

This is when you want to wrap up a few elements into something nice and neat like

<%= f.my_tag :user_id, @user.id %>

The code to make something like that was such a WTF moment for me that I had to physically take a step back from my overpriced macbook pro and take 3 solid, slow breaths before I could get my wits about me and dive into content_tag hell.

ActiveRecord syntax

I used to be a fan of ActiveRecord, I always thought it had that special something that made interacting with yucky mysql, postgres or sqlite palatable and sane. That is until I realized that it’s hurting me more than it’s helping me. I honestly don’t even know where to start. Wait… it’s coming to me, ok here we go, let’s start with something that should be easy, getting collections out of related objects:

current_user.todos.includes(:tags).where(completed: true).order(created_at: :desc).limit(30)

I mean, it seems like this does what I want, I want some todos and their associated tags based on the current logged in user, I expect this:

[
  {
    todo: {
      name: "todo #1",
      tags: [{name: "tag"}]
    }
  }
]

But this doesn’t happen, everything is wrapped up in an object and to get plain jane data out you have to introduce yourself to strange words like serializing and sometimes even gasp, marshaling. Honestly though, being a data marshal sounds like I’m about to have a wild west shoot out in the middle of town: it’s me, my keyboard and the gang of four.

ERB

This isn’t even related to custom form builder helpers, this is just straight up nonsense. If I had a nickel for every time I closed an ERB tag due to editor malfunction I sure as heck wouldn’t have to work anymore because I’d be a rich son of a gun. The idea of learning a whole other syntax on top of ruby and on top of rails’ conventions? I’m just trying to make a fricken website here not send a man to the moon, how many different things do I need to learn here?!

AR Callback hell

How do you get function reuse on a given event? Like for example when an object is created? Well you type after_create and then you call a method, sweet. Done. Of course what no one bothered to tell me is that the reason I even need these hooks in the first place is because we aren’t just calling regular functions to begin with, we’re calling a complex chain of methods so deep, it makes the marianas trench look like a kiddy pool. What’s the alternative you ask, how can we call a function every time a new database record is made. Well, it’s called a function, and you could just call that function where ever you want to save that thing, you don’t need a callback, you don’t need to learn another thing and get lost in debates about whether or not it’s after_commit on: :create or after_create. You can just call a function.

Criticism is the sincerest form of make a new framework

Which is what I did, I made yet another full stack framework, except this one isn’t in ruby, it’s in clojure. It also doesn’t have a lot of stuff, it doesn’t have a separate templating language, it doesn’t have an ORM, it doesn’t have AR callbacks or special content_tag methods, it uses functions and that’s pretty much it. If you made it this far you’ve got to be interested, check out the quickstart and let me know what you think!

Originally posted on medium

Discussion

pic
Editor guide
Collapse
kida001 profile image
Brian Vogelgesang

Is this some clickbait article to plug your new framework? Maybe you don't understand Rails? None of your points are flushed out, or in my opinion actually point to some of the issues Rails does have.

AR Callback Hell
Just because you can use those hooks, doesn't mean you should. Any PR I review that doesn't have a good reason for a before/after hooks would get rejected. Create explicit objects to handle your business logic, don't stuff them in the model where they get executed any time someone wants to create or update a DB object.

If you're in callback hell, it's because you made poor architecture decisions.

ERB
What is so complex about ERB, it's no different from any templating language I've used. You write HTML, and when you want to escape and execute code, you use <% insert_code_here %>.

"If I had a nickel for every time I closed an ERB tag due to editor malfunction..."
Maybe you should learn how to use your text editor

AR Syntax
current_user.todos.includes(:tags).where(completed: true).order(created_at: :desc).limit(30)

Do you know what SQL it takes to create the above AR Syntax?

SELECT *
FROM todos
WHERE completed_at is true AND user_id is $user_id
ORDER BY created_at desc
LIMIT 30;

Are you complaining that AR is too complicated for you? I'd say it's a hell of a lot cleaner and easier.

And yes, actually, the practice for any up-to-date rails application is to use a Serializer, which will eager load your associations if they're requested and let you abstract your response where it belongs, outside of the controller.

If you'd done any light reading on Rails, you'd take advantage of the things it offered, likes scopes, serializers, and pagination...

Serializer:

class TodoSerializer < ActiveModel::Serializer
  attributes :title, :description, :completed

  has_many :tags
end

Controller:

def completed_todos
  render json: Todo.where(completed: true), include: :tags
end

It literally requires that to return a JSONAPI compliant response with ActiveModel Serializers and Kamanari.

Your arguments are pretty moot, but maybe it's because you're trying to plug your framework. You would have done a much better job if you just explained the benefits of what your offering, without trying to shit on something.

Collapse
swlkr profile image
Sean Walker Author

I had to do a double take because I thought you were DHH for a second.

Thanks for taking the time to teach me all of these things! I needed it!

Collapse
adrienpoly profile image
Adrien Poly

I am sorry but if your goal is to advertise for your new framework why do you start by criticizing others👎👎👎👎👎.
Just spend more time writing about the benefits.
I read your GH project and I have no clue why your Framework would be better suited for my job. In which case does it bring a benefits etc.
Or at least you could take a Rails way of doing things and put side by side your way of doing things

Collapse
mtarnovan profile image
Mihai Târnovan

Are you trolling or just link-baiting? You don't even need to define a Serializer for this...

current_user.todos
  .includes(:tags)
  .where(completed: true)
  .order(created_at: :desc)
  .limit(30)
  .to_json(only: [:name], include: :tags)
Collapse
blissofbeing profile image
Wayne

To be fair ERB isn't a Rails thing, it's the standard Ruby templating language, and I see it as really no different than most other standard templating languages.

Collapse
swlkr profile image
Sean Walker Author

This is true, something like slim or haml could solve that problem at least.

Collapse
metacritical profile image
Pankaj Doharey

Any moderately complex Rails App is a nightmare to maintain. What havent i seen in the past few yrs of Rails Development.

Starting with Skinny Controllers fat models.. ohh no now the Models are fat!
Well lets use decorators to trim some fat, but wait what about the complex logic that may not fit here? Ahh we have concerns, the only problem is this damn concern has no concern about breaking the MVC!

Few weeks and say, You know what lets extract the business logic and concerns into a external loading library that makes so much sense right?

Few months down the line, hmm i think since we are already using an external library let us "gemify" the library and host it in our internal gemserver. Some features and few weeks later lets gemify all major parts of the Application!

Some more features and few months down the line, lets refactor the s*** out of this code its becoming too complex.

Few more months half a dozen refactoring later, you know what this is getting out of hand lets look for a solution outside of rails ecosystem. After a bit of searching and looking at other rails installs and conf videos.

Aha, just rediscovered SOA (Service oriented architecture) but wait we are hipster rubyists lets not call it with a bigoted evil corporatized name like SOA, it needs a Hippie name, as ascribed by our beloved benevolent dictator DHH.

Lets call it "extraction of business logic" into services! or maybe something simpler like Lambda Architecture?

Well, after some time and few api requests later,

Hmm you see since we have already extracted few of the business logic as gems and then as independent services modeled around lambda architecture (because thats the most hipster thing to do plus i like netflix). Lets rewrite the services in golang or Java or Scala to make it faster. Yippie!!

Meanwhile the other rubyists, meh, i am not going to install JVM on my machine lets look for another VM to install, that can be used to spin our new services.

Suggestion: Well lets use Erlang VM because Whatsapp used it and Dave has written an awesome book on Elixir a new lang on Erlang VM.

Thats your rails app story!

Collapse
nscmnto profile image
Bruno Nascimento

So what’s your solution/alternative?

Collapse
twof profile image
Alex Reilly

I'm getting into rails at work right now and I have a lot of the same gripes, but I've also only been using it for a couple weeks so I'm hoping concepts will come together with more experience

Collapse
metacritical profile image
Pankaj Doharey

I personally think not to spoil your mind with rails MVC architecture, it doesnt hold long beyond a basic blog, it breaks down easily even under a moderately larger app. The conventions are rules with their own peculiarity which moves you away from the problem.

You end up solving the framework to work for you than working the problem and let framework fit in place. Its almost ridiculous to keep battling the Rails framework to fit your problem domain.

Occams Razor suggest that simplest answer is also the most probable. The simplest answer is Routing + templating + middleware (RTM) not MVC. Use nodejs, clojure or Sinatra. Anything but rails if you are aiming to go beyond a blog and not want to battle the framework.

Collapse
twof profile image
Alex Reilly

I see where you're coming from, but I'm an individual contributor working with a small team on an existing project, so I can't exactly waltz into engineering meetings and be like "let's start from scratch using a framework that no one knows" hahah

Thread Thread
metacritical profile image
Pankaj Doharey

Hahah, True! I have commented above in the parent comment section do read it. I explain exactly how rails teams eventually hit a wall.

Collapse
swlkr profile image
Sean Walker Author

You know what, yeah the concepts will come together, stick with it! Rails is still a great framework to learn.