Put Chubby Models on a Diet with Concerns
37signals.com
37signals.com
It presented an argument, offered alternative viewpoints, and articulated why the author thinks his approach is better than alternatives (without overly attacking them). Code samples were provided with real-life examples.
Whether or not I side with Concerns or DCI or something else, I got value out of reading this post and my understanding of Concerns improved.
This is a welcome relief to what was becoming a tense and drama-filled debate (Rails OOP design). Nice work, dhh.
I've never been particularly involved in any programming communities and I am having a hard time imagining what it is like.
If you want more, just check out the tweets between @dhh, @garybernhardt, and friends on Twitter yesterday. There are also links in there to blog posts and code examples using DCI, DAO, etc. to achieve similar goals.
IMHO, this is one of the more interesting debates. Of course, not everything can be adding 'coffeescript' to Gemfile: https://github.com/rails/rails/compare/9333ca7...23aa7da
I couldn't agree more.
People treating the single responsibility principle as the holy grail keep advocating an object for everything. In more complex cases, you may need an object for something, but not in every case. In those simpler cases, I think something like what DHH's example advocates is more appropriate.
Viewer.visible(current_account.posts, to: current_user)
That's essentially a function inside a module/namespace. You aren't making a separate class/object for it.It doesn't get any better by having Viewer.new(current_account.posts, current_user).visibles or #execute or whatever else you'd do in a query object.
(Highly amused formerly chubby gal who felt fine about her body back in the day and got drawn into reading this piece by the ridiculous "sexist!" accusations -- highly amused because this stupid stuff might lead me down the slippery slope to actually begin learning to program. Thus any cooperation is much appreciated. Mmkay? Thanks!)
The problem is that eventually you get very fat models. You can easily imagine how much behavior something as common as a User might have, and you get massive classes that act like junk drawers for can_view_order? and can_order_new_item? and has_archived_orders? etc. DHH here is presenting a possible solution to that problem. There are links elsewhere here to other solutions.
Thanks!
In this context, DHH is pointing out that rather than duplicating the code for tagging and the code for managing visibility and the code for managing a Dropbox account on each class that needs these things you can use a Concern to abstract out each of those groups of functionality and then apply them case-by-case with one line of code. It's a pretty neat trick and used appropriately it looks like it would really help keep the model layer trimmed down to its bare essentials.
Thanks.
Less code? Yes. Cleaner code? Yes. Faster? Probably not detectably faster or slower.
It's not a problem for the computer if you have a lot of code in a single file, but it is a problem for the computer programmer. If there's a lot of functionality in a single file, class, or other grouping of code, that makes it much more difficult for a human to understand and remember the details.
It's easier to work with a project if you can break it down into small pieces that are each individually easy to understand, so a goal of good project organization is to make your code out of small parts - small files, small models, a small number of lines of code - and have the parts be easy to distinguish and remember.
If you split one big "User" model into separate bits for billing, authorization, and user settings, not only is it easier to understand what parts there are, when you need to go in and make a change to the billing code, you immediately know that 2 out of 3 of the pieces can be safely ignored.
Similarly, if you take some very common functionality that models often have and generalize it, you only need to learn the general version once and then it applies to each of the parts. That's what the article describes. Many models are "Searchable" or "Taggable", but you only need to learn how searching or tagging works once, and the same search or tag code applies in multiple places.
Thanks.
Let me unpack that claim.
In the models-and-controllers view of the world, there’s no obviously good place to represent the relationships between models. The relationship logic usually ends up getting stuffed into controllers (making them “fat”) or into arbitrarily designated models (making them “chubby”). For a long time now, though, everyone has been told to keep their controllers “skinny,” so now most of this logic ends up in models. And so we get a lot of “chubby” models these days.
Example time.
Say you have employees, who have roles at companies, which own assets. You’ll have a model class for each of these real-world concepts: Employee, Role, Company, Asset. So far, so good.
Now say you need a way to determine whether a given employee should be allowed to sell a given asset. Well, the answer to that question depends on the role that the employee has at the company that owns the asset. So where do you put the logic that answers the question?
Some people would put it in the Employee class, so they can write employee.can_sell?(asset). Others would put it on the Asset class, so they can write asset.sellable_by?(employee). Others would mix it into controller logic somewhere, because that’s where the employee and asset objects interact. And yet others would create a separate module of permissions logic to house the interaction, so they can write permissions.has_sell_on?(employee, asset).
If you choose to put that kind of relationship logic into a model class, and lots of people do, odds are you’ll make the same decision again and again. And, in time, your models will get “chubby.”
The problem is that, after a while, your models get bloated up with logic about other models and become harder to reason about.
edit: Apologies if that is heavy on the snark, it's early.
As for your characterization of dccoolgai's actions as being a "white knight": take your polarizing term back to reddit. Inaction in the face of speech that marginalizes a certain group only furthers that marginalization.
Also, dccoolgai, why did you leap directly to women's body issues? There are make models with body issues as well.
Allow me to respond to various issues with my initial call of “Party Foul” en masse:
The thing says “chubby” models on a “diet”. I know that could refer to males or females, but this article was not written in a bubble – it was written by a thought leader in a male-dominated industry using a tongue-in-cheek title clearly meant to attract attention and elicit a chortle by explicitly evoking body issues (and don’t give me “Rails is fat models and skinny controllers” – that stops holding water when you change the terms to “chubby” and “diet”)(And please don’t try to argue that society holds body issues over men as much as it does women – that sentiment is so patently absurd that it’s not even worth parsing.). There is no “conclusion” to leap to – it is laid out prima facie. I’m not saying this applies only to women, I’m just saying that society tortures women a lot more with body issues than it does men and invoking those issues for the sake of a “clever pun” is not worth it for several reasons, including but not limited to: 1. Reinforcing the perception that tech is a frat house. 2. Reinforcing the reality that tech is a frat house.
I love DHH and everything he has contributed to technology.
Nevertheless:
After further review, the call on the field of “Party Foul” stands. 15 yard penalty – still third down.
Doesn’t make DHH a bad guy. I know a lot women who are involved in tech specifically because of Ruby/Rails – DHH’s net effect on making technology a comfortable and inviting field for women to specialize in is vastly positive, IMHO. I don’t think he intended anything negative with either his post or its title. I’m just saying the pun he picked to put in the title of his post sucks. That’s it. For those of you whose knee-jerk response to this is “lighten up”: I respond in kind. I’m just calling a “Party Foul”, not trying to pillory your gods. Lord knows, I probably have and will say/write things that are much more insensitive than this… I just hope that when I do, someone will call me out for it in a thoughtful, non-reactionary way.
Because I don’t want to lose that much more HN karma over this (I don’t believe in this enough to sacrifice 50 points criticizing everyone’s idol.), this will be the last comment I make.
There are tons of people who work with engineers but who are not themselves engineers. These people will be even less likely to think "MVC models" and more likely to think "fashion model".
Another group is the general public or people choosing a college major or vocation. These people have never been exposed to MVC, so they will assume you're talking about "fashion models" with 100% certainty.
These last two groups are exactly the people who you don't (or shouldn't) want to feel automatically excluded.
You may as well paint a picture of the entire "tech industry" with a giant "NO FATTIES" sign.
The tech industry was borne of "geeks" and "nerds" and other such social outcasts. These groups of people were and are still being maligned as "virgins" and "having no friends" and "living in their mom's basement", etc. These tropes are only the more popular the larger and more dense the Internet becomes. But where is the outrage for the maltreatment of these individuals, who make up a now large segment of society (with the growth of the technology sector)?
Nobody cares, because you either identify positively with that characterization (I'm a real geek!), or there is such cultural inertia that the phrases have become no longer harmful (read: the euphemism treadmill).
Regardless, it's BS to suddenly jump to the aid of an extremely narrow segment of society because of a simple pun. I mean, honestly, despite our society having a real problem with female body issues, does anyone really feel badly for female fashion models? And can you demonstrate a similar defense for another segment of society that you actually identify with and feel needs protection? Because if you can't, then (like the phrase or not), you're just being a white knight because it makes you feel good about yourself.
Your bizarre rant about geeks is a problem which does not exist outside of high school and some corners of the internet inhabited by people still in high school. These geeks are not an oppressed class. At all.
I know fashion models. They have problems just like everyone else. Also, stop calling women females. It's really creepy.
You have some serious issues with your worldview.
We aren't spherical chickens in a vacuum here. Don't play dumb. You know the implications of the title. Do you realize how ridiculous "perhaps YOU are the sexist for noticing sexism!" is?
http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat...
This is the first I've heard anyone interpret "Model" in the context of software as pertaining to sex, gender, etc.
I find, DCI doesn't say much with regards to how you query that state or present it to the user. I don't need a context or role to query data. Concerns do seem to provide some really nice ways to "DRY" things up on that end.
Certainly you can use concerns to deal with interaction/role type issues, but then they really aren't all that "cross-cutting" they tend to be specific to a particular use case or scenario. In which case I think there are better options. DCI is one, domain services are another. But hey, if Concerns work as your golden hammer by all means. I have some doubts.
I don't see this as a DCI vs. Concerns argument. However, if you want to argue it isn't possible to do DCI well in Ruby (extend sucks, yadda, yadda, yadda) go right ahead.
A chubby model would be one that implemented its own versions of multiple cross-cutting concerns, no?
Great title though, very creative. And also a very good idea in practice.
I've got an abstract model 'PageLike' that contains a bunch of fields common to all page-like concrete models (title, metadata, content, last modified etc)
Or is there something more going on here?
It is sad that you are pre-emptively pulling the anti-feminist card, but it also indicates that you do not understand what actual sexism is, or why it upsets people.
The title is specifically intended to be a double entendre (and kind of a clever one). If you really want to disassemble this whole thing, it's the clever use of "diet" that makes the pun.
>Yes, he is trolling HN with the title, because you can get sadly predictable conversations like this one.
The article was published on the 37signals blog. I doubt DHH considers HN the center of the tech universe, given anecdotes of his general disposition I can't imagine him thinking "just wait until the HN crowd gets a load of this title".In Rails world, the topic of fat models (lots of impl methods, code, etc) comes up all the time. This isn't trolling. It's called being creative vs. "Use different code to remove more code from your models".
Gimmie a break..
And yes, like another poster said, I doubt DHH uses any thought or loses sleep over how HN will pick up the post and tear it down. He created a great framework, has built up an inspiring company, and wanted to share some thoughts. Doesn't go any further than that in my mind.
I have no idea where you get your conclusions from.
Ugh, I've just contributed some more. The only winning move is not to play.