Guide: Things You Shouldn't Be Doing In Rails
Posted by kev Wed, 30 Aug 2006 05:32:00 GMT
Koz recently checked code into core that kicks and screams all the way home if you’re using deprecated methods or instance variables. In honor of this I’ve decided to give you a list of things I still see over and over in Rails code that you really shouldn’t be doing anymore. Really. Trust me on this.
Update: There’s been enough controversy over this article that I’ve responded.
Accessing Instance Variables You Didn’t Create
It’s time to stop using the instance variables for params, flash, session, request, response and all of their formerly preceded by an @ friends. This has been deprecated for a while but it looks like it hasn’t circulated well. When you use the instance variable directly it makes it hard for the core devs to change the implementation. It also means you’ll have broken code sooner than later so kindly remove your @s. Yes, I know there’s still documentation that uses it. Please file a ticket.
rabble (who you’ll hear more from later) also suggests that you not intermix usages of flash[:notice] with flash['notice'] and the like. I personally prefer the symbol version and I’d encourage you to use that. You save yourself an entire keystroke and memory usage. What’s better than that?
Using Deprecated Finders
find_all and find_first have been deprecated over a year now. Stop using them. While you’re at it, stop using render_partial. Their better educated cousin find can handle all their needs. Use find(:first), find(:all) and render :partial.
Getting Ahead of Yourself
Stop trying to write “neato ajax driven thingies” before you understand how to write it properly without ajax. In fact, write the non-ajax version first. Always. It means that you’ll have a place to fallback to if the client doesn’t support javascript. It will also keep you from doing things like writing a separate action for the ajax and non ajax version of a form. We’ve got respond_to for that. Use it.
Stop asking for things not directly related to your problem. If you’re seeing an exception you don’t expect ask about that. Don’t ask about if anyone has heard of problems in some library. This really should be generalized for asking all questions: Ask your question directly and with as much information about the problem as possible. This doesn’t mean I want to see all of your logs and your codebase. This does mean that I’d like to hear what the error message is or what isn’t working. If you’re not using the latest version of Rails, please specify.
Fallin’ off the wagon
Scaffolding isn’t for production. Overcome your addiction. It shouldn’t be modified to be more customizable. Developers should instead learn to write Rails code. It takes far less time and should produce less mediocre code. It’s good for the screencast and not much else. Leave it alone. If you insist on a bootstrap database administration interface take a look at Streamlined.
Using Components
Components don’t belong in Rails. Don’t use them. They weren’t an extraction. They weren’t well planned. When you want to use a component it is probably because you misunderstand them or really want a partial. Rethink what you’re doing. The rest of the Rails world has written off components for a reason and they’ll probably be deprecated by 2.0. Resist.
Using Engines (Improperly)
Yes, I know you’d like to have an authentication system without doing any work. Yes, I know Rails preaches convention over configuration. This is not a place where it applies. This is, as we say back in the hood, “too much software”. It’s also a nasty hack that breaks every new version of Rails because it hooks into internals that aren’t publicly supported. These are akin to scaffolding. You’ll be happier without them.
Update: This could use some clarification. Engines aren’t de-facto evil. However, the way most people use them _is_. If you’d like to have the same functionality across several of your apps you may want to use engines. My problem with them is that they become a slipperly slope for drop-in turn-key applications. Don’t use them like that. As long as you’re not using them as a once size fits all solution, you’re probably ok.
Not Using Layouts
Please, take advantage of layouts. I’m tired of seeing broken views that include 40 lines of container stuff. Using layouts means that you and I both have less to look at to fix your bug. It’s also much DRYer so you get to make a single change to a layout instead of lots of changes to lots of views. I had to do that for a client once. Two hours spent on a tiny crappy website reworking headers. Don’t do this to yourself. I’ve reopened old wounds just thinking about it.
Using (The Built In) Pagination
A core member chipped this one in (which I’d been contemplating). I haven’t used pagination in my last 15 projects. The pagination code is ugly. Ugly ugly. Many of us would love to see it gone. It’ll probably be extracted to a plugin though so if you need it you’ll be ok. Look for this to be deprecated in the next few versions of Rails.
Oh, and if you don’t believe me, listen to rabble, former lead dev at Odeo and a Cabooser:
The paginator produces horribly unscalable code which will bring your server to a halt. – rabble
See? A halt! Sufficiently frightened? You should be. Update: If you’re one of the apparent many who took offense to these last few statements, you missed the grin I had when I wrote it. Don’t run screaming. Just be aware that using things that are (or will be) deprecated can cause you problems.
Now, stop using these things. It’s for your own good. I may do an article on the things I’m really happy about in Rails in the near future. Let me know what you think.
Oh, and take interest in your fellow coder and let them know about their mistakes by digging this guide.
Updates: The concept of pagination isn’t a problem. The rails implementation of pagination (and the associated helpers) can be. As for the scaling comment, pagination will work fine for a blog. You’ll start seeing problems when you’re working with tables with millions of rows. If you don’t need to deal with that it may not be a problem. Just be aware.
Update #2: I’m adding this just because Rick Olson of the core team says it so much better than I do:
Kevin’s speaking out against the Rails Pagination classes, not pagination itself. The Rails Paginator is difficult to use for all but the simplest of queries. It’s also inefficient in various ways.
Via Riding Rails.
Major Updates
My friend Chris Abad (sd.rber and all around great guy) pointed this one out…
Putting Controllers in Namespaces
This is really more trouble than it’s worth. You run into all sorts of crazy errors if you do this and you’ll be confused and frustrated. You’ll then ask other people about it and they’ll either blow you off for using namespaces with controllers or procede to get confused and frustrated as well. Then you’ll say, “I with I had listened to Kevin and Chris”. If you want /admin/some_controller as an URL that’s fine. Use the routing that’s built into rails.
For The PHP Trolls and Frightened Ruby Devs
I’m sorry if you took this the wrong way. This article is purely my opinion and some obviously disagree with me. The important thing to note is that although I consider these things rough spots, I’m still a die-hard Ruby and Rails coder. The feeling (and speed) I get from working with these tools can’t be found in any other language or framework. Period. Don’t be afraid because there are pitfalls – that’s true in any situation. Just be aware of these things. I’ll post a list of the things I love about Rails (and you may want to use) later in the week.
Book-wise, you’re still in good hands. Agile Web Dev with Rails is being cleaned up for the second edition. Ruby for Rails is quite good. These guys won’t lead you down the wrong path. This article is just meant as a wake-up call to those who still haven’t heard about the updates.


Interesting read. Pretty much all of my limited Rails knowledge comes from the Agile Rails book.
Is there some kind of official list of all the things that were once common practice but are now horribly deprecated as well as their accepted alternatives? I think that would help a lot of my confusion with Rails. Obviously the new code you mentioned will tell me when I’ve used something deprecated, but it would be nice to avoid the mistakes before I make them.
And as far as pagination goes—don’t use it ever, ever? There must be instances where paging is helpful and can be done without too much overhead, right?
Rob: Pagination is a fine thing. Ours just has some issues. When I use pagination I do custom pagination with the Paginator object. I’ve heard of other Rails coders I respect doing the same.
What should we use to paginate a large record set? You mean we should not use the pagination helper and use the Paginator object instead? or make our own pagination implementation.
These kinds of articles are great, but you know what would be better?
http://deprecated.rubyonrails.org …as in when deprecations get logged with a nasty message, they could say
“xxx is old and busted!!! – visit http://deprecated.rubyonrails.org to find out why and to see what to replace it with”
It would be nice to have a central resource to point newbies to (cough30%_of_rails-talkcough)
Could you elaborate on the “Putting Controllers in Namespaces” ?
What kind of errors ? Why do they happen ? How exactly should we use routing instead ?
Wanderer,
generally things get a little messy. One fantastic error i got (i can’t remember the specific message) but if you have an admin model and try and create an admin controller to inherit from. Check out this post for more information.
Kevin,
I would agree with everything you’ve said;
what is a good alternative to using pagination for large or small data sets? producing XML????
What’s a valid error that you’ll see with modulized controllers? I don’t use them often, but I’ve never had a problem with them…
This is great, but I really think that you need to expand on that pagination point! Can you imagine something like Flickr without pagination. What should we be doing?
“The rest of the Rails world has written off components for a reason …”
I just got the updated Agile Web … Rails PDF, and, sure enough, it still covers components. If Dave Thomas and DHH are bothering to put them in The Offical Rails Book, why are others insisting they have been written off?
Fortunately I haven’t much of these in my projects, but still: Why isn’t this in the official documentation?
Oh, and funnily enough it’s not only not in the documentation, but that bit about namespacing controllers is advertised in the freaking script/generate Controller help message…
Very useful article. Things move so fast in the Rails world it is hard to keep track of the new practices that out date the old practices. Few quick comments:
PaginationI agree that pagination can be misused. Not just from a performance standpoint. From a UI perspective it is overused. Having “next” and “previous” links tell you nothing. The user has to simply click page after page to find what they are looking for. Things like alphabars and categorized results can provide much more info to your users. It requires really thinking about your data to determine the best alternative to pagination. Sometimes simple pagination is the best way but often there is a better alternative.
ComponentsI personally don’t agree that components are bad. There are some performance considerations (since an action must be executed which can be expensive) and partials are often a better choice but sometimes a component makes more sense from a software design perspective. Caching can often overcome the performance hit if it becomes an issue although I find limited usage of components do not introduces a significant performance hit.
EnginesI also don’t see the problem with engines.I just see them as a plugin which can easily contain views, models and controllers. I have found the login extremely useful and other engines such as a wiki engine, message board engine, etc could also be very useful. Sure you might have to override some of the functionality to fit your application but what you do not override is now being co-maintained with other people. This reduces your development time. I don’t consider generators a viable alternative. The login generator has been enhanced over time. If I had generated my code from an early version I would have to manually upgrade. With engines I can just svn update followed by a quick run of my test.
The fact that the Engines plugin uses undocumented API and can break on upgrades are just an implementation issue. To me this just points to an inadequacy in Rails since it doesn’t provide a real method for this type of interaction. Even with the inadequacy it is not something that the developer needs to deal with. If Rails breaks the Engines then a developer simply needs to wait for the Engine code to be upgraded. Until the upgrade is made the developer can keep the older version of Rails.
_Overall your article is great. It’s helps get depreciation info out to developers which is not well documented in other places. Even for the case of pagination, components and engines I think developers need to understand the drawback of using those technologies and really evaluate if they are right for their environment.
What’s wrong with namespacing controllers as long as you don’t name a controller the same as a model?
As for namespacing controllers, we’ve been trying to add support for this for a while in Streamlined, and it wreaks all kinds of havoc if you are trying to do anything at all with require_dependencies or depend_on. Inscrutable, unspeakable, Cthuhlonic things.
Nice – I particularly agree with the sentiments about AJAX – too often we run before we can walk. It’s good to keep in touch with which aspects of the Core might be being deprecated, but it’s also important to remember that a lot of what is covered here falls into the realm of opinion.
The particular types of applications that are commonly developed by the core may not use pagination or components, but that doesn’t mean they’re evil, it just means they’re less and less likely to see any love as Rails grows more mature.
If the pagination code currently sucks and doesn’t scale, then somebody please write something better! It’s a ‘PDI’ moment, not a ‘run away as fast as you can’ one. It also seems like you may have misunderstood the point of engines, possibly. I’ve reworking the opening sentiment on the engines site to try and make it really clear what they’re good for.
Less vilification and more context helps promote better development practice, IMHO.
Sorry, but you’ll have to pry pagination from my cold, dead fingers…
Here’s a spiffy idea: instead of adding feature after feature after feature after feature after feature, then telling us “Don’t use , is LAST WEEK’S CODE!” ... how about we stabilize a little bit?
If the Rails devs continue to introduce and then revoke useful, time-saving features … then where is the advantage of using Rails? Sure, off the cuff it might be 10x faster than developing in Java… but that’s only a savings if I don’t have to go back later and rewrite it all anyways.
(don’t get me wrong; I much prefer writing in Rails than in Java … and I love the Release Early & Release Often approach … but lately I think it’s transmogrified into “Release Early & Revise Often”)
Should we avoid just packaged components or even just rendering components from the standard structure. It seems to me that components fit a very legitimate need: that is rendering a partial that needs something fetched from the database. Are you saying components are bad from a performance perspective? Are they destined for deprecation?
The alternative to me seems to be before_filters in application.rb to fetch whatever is necessary for the partials in questions (think sidebars). It seems less DRY.
On the pagination front, I’d like to see the implementation fixed. It’s all fine and good to talk about alternative formats, etc, etc. But let’s face it, pagination is used in some form by the majority of database-driven websites, and with good reason, because no matter how fine-grained your search, if your site is successful you’ll have too many results to fit on one page eventually. Pagination is a baseline efficiency measure.
What I don’t understand is why pagination is so ugly, and what difference using a custom Paginator makes? It’s not that complicated, you need two queries right? COUNT and LIMIT X,Y. I think moving it to a plugin would be a big mistake.
Hi guys, I’ve added some updates to help clarify some of my comments. Ping back if things are still unclear.
Overall, a very well-written piece. But mmake sure to always detail the new way of doing things whne you dis the old way. e.g. pagination.
I’m using namespaced controllers on a fairly large project, and haven’t had any problems. It’s much better than mixing all your admin actions in with your public actions, IMHO.
As far as components go, the implementation is poor, for performance reasons, but they can be useful in some situations when you don’t want your code to turn into linguine.
Mighta been a smaller list if you instead just listed the things allowed in rails. :)
OK, so another person using the ‘more trouble than it’s worth’ attitude about controllers in modules.
I’m using them; the concept was in the book, it provided structure and cleanliness to my app (not least in the controllers directory), and it sits reasonably well with controller inheritance.
But largely because I ran with it and it worked OK.
I now have a dozen or so admin controllers in a (two level) admin namespace, in a production app. I’ve seen a couple of small issues, but I’m not sure why all of a sudden it warrants the ‘blow you off for using namespaces’ tone.
It was in the book, for flipssake. OK so the core team didn’t think it was worth the test cases, but there are people using it, and until the second edition of AWDwR replaces the first, this poorly communicated “those who are in the know, don’t, m’kay?” attitude is just going to piss^Wfrighten people off.
I think Rob Sanheim’s suggestion is excellent. deprecated.rubyonrails.org is a great idea.
Mostly good, but your recommendation I not use pagination is amongst the more ridiculous I’ve read.
For people moving from PHP/ASP into the rails framework its hell because not only is ruby a bit different the rails framework is constantly changing and we have no idea whats the new “proper” way to implement proven concepts in other languages.
The biggest problem with namespaced controllers is that, like so much else in Rails, the only people that know how to use them correctly are the core team because there’s no frickin documentation (the core team considers the code itself to be the documentation). The rest of us have to wait a year or so for another overpriced book or conference to find out about something that will be deprecated in favor of something equally mysterious and undocumented before we even finish writing our code.
90% of the namespaced controller problems that get asked about on IRC are from people who want both an Admin controller and an Admin::WhatEver controller. Obviously routing is going to have a problem with that.
More than half of my controllers are namespaced, with zero problems.
“You’ll start seeing problems when you’re working with tables with millions of rows.”
Is this problem related to it having to do a count? Because yeah, that’s necessary when paginating.
I made a small app for those 36 million AOL search results and the pagination code wasn’t a problem at all. The count query was time consuming, but more or less unavoidable if you want to display the total number of pages; you can cache it, or even through it off to a BackgrounDRb process if you want.
I think you’re way off base here. Can you go into more detail about the supposed performance issue?
What I really liked about namespaced controllers was the convention-over-configuration nature. I’m just not convinced that the replacement is as simple.
You forgot to mention <%= yield %> instead of <%= @content_for_layout %> in layouts
Great post… but I’m confused on the first point “Accessing Instance Variables You Didn’t Create” since the Rails book says do it that way… what’s the prefered way of accessing @params, @session, etc.?
Great Writeup. If you namespace both your controllers and models there are little problems until you need to link outside of your controller. Namespaced controllers can be a real pain with url_for. No end of problems really. They can help make a large app, think 20+ models large, a little bit more manageable. And if you take the time to figure them out you dont need to be in the core to understand whats going on.
Hmm…
Once again, more information that is buried in hundreds of places, but not it the official docs.
Get your shit together and modify the official documentation when things ARE depracated or no longer sanctioned.
Rails rocks, but the lack of documentation is its achiles heal! this is getting to be rediculous.
Wog, If you’ve got a problem with the docs, do something about it. Honestly, it doesnt’ effect me. I write documentation patches for you guys. I don’t need them.
We use pagination for our app.. and we have almost 500,000 records in our db and so far we hv no issues with it. So I’m sure its a matter of how you use it.
As for Rails Engine, its wonderful. It works right out of the box. I have to agree to the point where if it fits your need, then use Rails Engine. It will not help you much if you need to build your app around it or worst make significant changes/overloading it.
And the Rails Engine people have been on top of it, especially with the 1.5 release that broke engine.. they released a patch almost immediately.
mommy, daddy, stop fighting
ben, Instance variables used to be the way to access those things so the book showed that. For a while now that’s changed.
There was a blog on Riding Rails about it a while back:
http://weblog.rubyonrails.org/2006/4/25/use-params-not-params
Whoa.. most of this stuff seems like common sense! I’m nervous about those people who are still doing these things. Excellent refresher. Thanks for posting!
All those core developers who have commited that all that bad code into Rails should have their commit bit taken off.
All those core developers who have written articles, books or blog entries about those bad coding practices and features should have their commit rights taken away.
Who ever had written those @flash and @session variables into Rails code belongs_to :that_group.
People who have written Ajax support into Rails has_many :sin_commits.
All those core developers who need more than one page at their real applications has_one :pagination_sin used.
Seems that validates_instance_of :good_thing returns nil when Rails is concerned. How can such a small core team produce so much bad things? Can we trust that they can even deprecate right things?
I’m not so not serious not, but could not not resist. Have fun.
Still Nil Missing
Nice tips…thanks for the helpful info. However, I’m also with Mike a bit here – seems like half of the info in the various Rails books I have is now deprecated.
From the sounds of it, there’s no reason to buy any Rails books, as code within said books could be bad practice by the time you’re through with the book.
Nil, Some things don’t seem bad at first and every software package has problems. Such is life. Rails is still head and shoulders ahead of the competition.
And don’t get me wrong, this isn’t about bagging on the core team. They do a great job. Some practices (and documentation) just need to get up to speed with the codebase.
What specifically is wrong with the pagination rails provides. I’ve read all the comments and the article twice. It’s still unclear as to what specifically in Rails doesn’t scale. Is the paginate method on the Controller class the problem? Or is it Paginator class that doesn’t scale?
I stopped using paginate because I want to drive all my Model.find calls into methods on my objects and paginate doesn’t work inside model classes. Instead I create a Paginator object, but that requires that I query twice once for the count the once for the records. Is that why you’re saying it doesn’t scale? Maybe you could give us some details as to why it doesn’t scale.
Just calling something evil and bad only alerts me to a problem, but leaves me with a WTF do I do now look on my face.
~:-0
I have add another vote for pagination being a good thing. In the app I’m working on right now, I’ve implemented a fairly precise search capability, but even a highly specific search can return 400+ rows. Am I supposed to just dump all of them to the browser? Plus, as a user, sometimes you don’t know what you’re looking for until you see it, so you expect to be able use a vague search and scan through the results.
Otherwise, I really liked this article, but maybe that’s just because I’ve been lucky enough to follow most of these recommmendations by chance…
Stop blaming the book, people. It was bad to rush out a book with bad style, but that doesn’t mean you can’t think for yourself.
Accessing instance variables directly is a generic OOP no-no, nevermind Rails, nevermind Ruby, which doesn’t enforce the principle either, but that’s not a mandate for bad style.
To this end, I’d actually prefer a way to declare instance vars for views that was truer to that concept, as well. For now, it’s not really a big deal, and it does help to pick out the data the view will be using. But still.. this encapsulation thing is a good idear.
Now, to be fair, if you saw @params (for example) everywhere, you might not think to look for params(), but I dunno.. I read these same books, but somehow I managed to figure it out. Well, I and the people that wrote the books, the blogs, the emails, the people on IM, on IRC.. There’s plenty of good and bad information out there, but always think for yourself.
> Accessing Instance Variables You Didn’t Create
That goes for all Ruby code, not just Rails.
I haven’t had any problems “putting controllers in name spaces” (AKA controller modules). Rails’ generate handles them just fine, even generating functional tests:
./script/generate controller admin::items
Also, I find putting controllers in namespaces much more preferable to having monolithic controllers. Before I separated my controllers into namespaces, I had a lot of code like this in each: etc. Now I just define them once (yay, DRY!) in the base controller, and subclass those. Namespace controllers are the way to go.
We’ve got respond_to for that. Use it.
Only if you’re using edge, correct?
Very helpful, but any of these kinds of best practices or pitfalls really should be part of the docs. It wouldn’t take much more effort to add some of these warnings into the relevant sections than it did to type this post up in the first place.
And didn’t we just raise $16,000+ to hire someone to imrove the docs? Surely some of that money could be spent towards consolidating things like this post and others like it back into the rdoc?
So both components AND engines are bad? That seems to leave Rails without any significant way to incorporate external code that is more complex than a plugin.
Yes, there is code generation, but as others have pointed out, that makes a big mess for maintenance. Yes, I’ve seen the Generation Gap pattern – but how should one “subclass” a view?
Yes, the implementation of Engines is fairly complicated. But this seems to arise more out of the division from the core – maybe I’m crazy, but if an Engine-like mechanism existed as part of the core Rails system, all the “hidden implementation details” would stay hidden.
This post is well-intentioned. It’s also somewhat pissy, accusatory, and misleading. There are times you have to use Pagination, and implying that it never should have been in Rails is less than helpful. If the Paginator is broken, then someone should work on a fix.
There are times when you should finish writing something and then put it away for a few hours or days before hitting Publish. This was clearly one of them. If being involved with the Rails project makes you this pisstrated, maybe you should think about a different hobby. I hear gardening is nice.
Joe Ruby, Not everyone has issues with namespaced controllers. I’ve regularly run into them so I suggest using alternative methods. These days I’m doing REST stuff so my controllers get split up anyway.
I’m 90% sure that respond_to went in for 1.1. Anyone else recall?
Kevin,
You should lose the patronizing tone and offer up solutions to the problems you point out. Your “guide” is much like most of the rails documentation I see out there—A lot of hot air but not much content. Luckily the framework itself is good enough to transcend all of the garbage Rails experts write. Prove that you’re better than all of that. Prove that you’re a Rails mensch and make your next post an actual guide. Call it “How To Fix The Things You Shouldn’t Be Doing In Rails.”
Kevin: What issues have you run into with namespaced controllers? Are they solely related to REST stuff?
For someone bitching about web development, your site sure is UGLY.
Nice article, btw ;)
Jordan, If you’d like to redesign my site, be my guest ;) . I’d rather provide content than spend the time to rewrite the template. Maybe when I move to mephisto.
Kevin, I think you are.. uhm… somewhat inhonest. Instead of saying “don’t use” say “fix it”. Instead of saying “doesn’t work” say “it’s broken”. Namespaced controllers (as well as namespaced models) Should and hopefully Will work (simply because it’s insane to omit namespaces like Rails does).
Instead of saying “don’t use pagination” say “pagination code needs fixing”. Or you think that loading a couple hundred thousand objects into memory of our shared servers for iteration is a good plan?
@Seth, True, you can’t put the onus on the book for doing everything, but when it’s written by DHH and you’re a beginner to Ruby and Rails, it can be tough to seperate what you should do now and shouldn’t do later. (In these comments alone, there has been infighting about whether or not pagination should be used. For a beginner it’s going to be tough to seperate what’s right and wrong, even when thinking for themselves.)
Although even my grandmother knows not to access variables she didn’t create.
Even my grandmother knows it’s separate, not seperate.
Julik, I’m sorry if you feel I’m being less than honest here. I suggest people don’t use things that are broken. By all means, if you know how to fix the situation do it. But I expect that most rails developers haven’t hacked at the core and would be better served by avoiding the problem in the first place until someone who can fix it does.
I’m a Ruby newbie (brand new), but a veteran programmer coming from the PHP camp for my previous web development activities. I have “Programming Ruby” and “Agile Web Development with Rails”; the latter of which I paid to have shipped to me overnight. Fortunately I’m hard headed and I still intend to go ahead with my Rails development, despite the scary tone of this article and the comments that follow it.
This article could easily have been titled “How To Scare the Crap Out Of A Potential Ruby Developer.” Now I’m wondering if the Agile book I bought was a waste of money and how I can find good docs on writing code without components and engines.
The first thing a manager ever told me was: “don’t come to me with a problem until you have at least two solutions”.
In closing, thank you for the additional information I found in this blog post. It definitely is useful and I’ll add this blog to my feed reader. But I can’t shake the feeling that a legion of PHP evangelists just popped a champagne bottle.
Robert, I hope the new section under the Major Updates heading addresses your concerns.
Engines are in fact de facto evil.
Kevin – thanks for the article. Some good heads-up things here, whether everyone agrees with them or not. Maybe you should divide your points into “depreciation warnings” and “(my) best practices”.
I like the idea of depreciated.rubyonrails.org, but I think even better than that, I’d love it if someone could write a rake task along the lines of test:functionals:depreciated or something like that. I know to use find(:all) now, but I know I’ve used find_all in the past, and it’s hiding in code I may not look at much anymore.
I think pagination is more of a style issue – I agree with some of the comments that mention if you have more than a few pages of records, who is going to sit there hitting “next” or “previous”? You’re going to need to write a custom solution for those situations anyway, maybe offering the end-user some sorts and filters, etc. The built-in Pagination is about as useful as scaffolding – it’s nice to see how it works, but once you start on a real app you’ll replace it real quick.
I still use modules with some controllers. It helps me keep my code organized, and I think if you’re using the right names for modules you can avoid conflicts and you can avoid too much trouble.
For the record, I wasn’t blaming the book. I LOVE the book. The book stopped me quitting software development. I just think people need to see a single, reasonably authoritative site explaining how things have moved on since the book.
The point is that the book is brilliant, and it sets a standard for accessible documentation that is lacking for these new approaches. You can’t expect every new user or even every seasoned engineer to want to subscribe to a disparate bunch of fast-turnover RSS feeds and filter various levels of opinion, attitude and I’m afraid quite frequent smugness in order to get their information.
As an aside, the author is totally right on components, but I’d love to see concise posts about better approaches to pagination and moving away from controllers in modules. Take pity on the poor guy who had to think about something other than code for just a couple of months, and comes back to find that everything he’s learned is old, granddad…
Jason, What prompted the article was changes in edge that cause warnings (lots and lots and lots of warnings) which tell you you’re using something that’s deprecated and may break soon. A rake task would probably be nifty in the mean time. Poke me if you write one and I’ll link it.
Still waiting for a reply.. any reply.. to the oft-repeated question, “What do you mean by not using pagination?”
Are you saying, always show everything on one list? Or custom write pagination? Or don’t use the pagination helper?
How is it broken? Why is it broken? If people need pagination, what should they do?
Re: respond_to && v1.1
Yep, it’s in there, in 1.1.6 at least.
I feel alarmed:
http://jooto.com/blog/index.php/2006/08/31/trouble-in-paradise/
If I were you, I’d remove your Pagination bit so you don’t mislead impressionable people into not using perfectly good tools.
I’ve responded to some of your comments here:
http://glu.ttono.us/articles/2006/08/30/on-the-days-events
Feel free to air your grievances there.
For everyone saying to update the documentation, it is updated…in the trunk. If you are using a version before the decision was made to “change” best practices or deprecate functionality, then when you download new releases, you will have correct documentation. Work is in progress to improve documentation outside of the source and cover multiple versions, be patient it’s coming.
Also, put the RubyOnRails Weblog in your feed reader, core is usually pretty good about putting current and upcoming deprecations in there.
Keep in mind that the statements Kevin made were his opinion based on experience (and of his friends) and following changes in core development.
One last point, the AWDR is not the definitive guide to programming in Rails, Rails has changed dramatically since the book was released, ditto with version 2 I’m sure. It’s a great book, but just because it showed how to do something at the time it was written, doesn’t mean thats how to do it today.
assert !core_team.include?(‘Dave Thomas’)
Components != partials
Partials are view-related: they render information within the context of the current controller.
Components are controllers + views that you can put into a view that belong to some other controller (or controllers). They are different from partials in that they are designed to gather and present their own data separately from the controller that’s actually preparing the current page.
Partials don’t replace components. Partials are not a “better” sort of component.
If components ever get deprecated, the DRY implications for applications that genuinely need them will be disastrous. All that controller + view code will have to be copied across multiple different controllers.
With respect kev, if you don’t see the importance of components then you just haven’t personally found a legitimate use for them yet. But that doesn’t mean they’re not a powerful and important part of Rails.
> find_all and find_first have been deprecated over a year now. > Stop using them. I find it ironic that “find_all” is actually still used in the standard Rails README file generated with every new project.
Your very good article here is putting focus on the right things. I hope it spreads to EVERYWHERE in the Rails source — not just the fun code part.
I’ve put together a plugin that tries to find these problems in code and warns you about it.
I’ll update it as other parts of Rails are deprecated in the future.
Deprecated Verification Plugin
As a new-to-Ruby and a conscientious developer, I want to avoid doing things in Ruby/Rails that are no longer considered best practice… This article mentions that we should stop using the find_all() and find_first() convenience methods. Does that apply to the find_all_by_XXXX() method as well?
Re: pagination. So where’s the knee of the curve? I don’t have millions, but I do have tables with ~1500 elements. Is that a performance-killer or not? What should we be doing instead of the built-in paginator? Is there an Edge Rails implementation of pagination that’s better? Thanks for the great summary.
Good stuff for the most part. Newbie Rails developers definitely need a kick in the pants sometimes to get them on the road to good practice.
And reminding people about deprecated (and perhaps poorly thought out in the first place) features is a good thing.
I posted a response re: Engines based on my personal experience with using engines for my autoDB plugin. If it’s a bit harsh, I didn’t intend it as such.
Check it out at http://www.yehudakatz.com
Perhaps this is a “duh” question, but it truly does baffle me. With the adoption of REST/standardized resource routing, what exactly is the issue with scaffolding, provided someone looks at the generated code and modifies it to work with their application? I recently used scaffolding for an application I’m moving to production, and it worked rather nicely. I looked at my generated code, added before_filters to protect the administrative actions, changed list pagination to work more correctly with my application, removed the index method and renamed list… No, the generated code wasn’t exactly what I needed, but I felt like I saved time tweaking the various filters to mesh with whatever that particular bit of the application needed than I’d have spent writing much of the same code again and again.
I think it’s a crutch if you don’t understand what is happening, but I think it’s quicker if you’re trying to write a CRUDdy, RESTful app and only need to modify small bits of what was generated. I also think that it was a crutch when DRYing up actions was encouraged (I.e. the Rails Recipes section on making one edit action for new/create/edit/update) but if Rails is encouraging resources, then why not modify scaffolding to be more in line with that, and why not use it if you understand it?
Eric, The dynamic finders (find_by_xxx) are just fine. Feel free to use them. Only find_all and find_first are deprecated.
Btw Kevin, why does core team deprecate things? If thing are so bad as you say, why not remove them right away? That way things get fixed immediately, instead of lagging and nagging forever. If bad practice is not there, then those without know cannot use it!
Or is there some specific date set when all deprecated things are erased from Rails? If not, you should set one. Otherwise “deprecating” things is itself a bad practice (not best practice) and should be deprecated.
For Apple users out there, I created a growl notifier plugin whenever a deprecated function gets logged. Check it out.
Oh thank you for pointing out that namespaces are evil.
I started using them, and suddenly all my url_for and link_to screw up. I eventually had to rewrite all references to controllers with a preceeding ”/” (like ”/main”) to fix it.
The idea of just using routing (and naming the controllers “AdminLogin” instead of “Admin::Login” instead?) is very good. I’ll try to rewrite my project this way.
Thanks!
I don’t know why you’re saying namespacing is bad. I think it’s a bit of BS.
Yeah it can lead you into hairy situations but if you actually understand how namespacing works (and don’t mind to apply some common sence when you come into problems) then they’re fine.
Namespaces is one of the awesome things that people from PHP get to look foreward to :)
Has anyone got some real proper criticism of namespaces besides ‘they’re bad’?
Great article, it helps to have it summarized in one place!
However, I agree with the aforementioned comments that components are extremely useful. They make developing portal like functionality where you want an area of dynamic content repeated on different pages very simple and DRY.
I have been unable to find a similar approach to combining business logic and view in a reusable component in an equally DRY manner without using components. It would be helpful if someone could provide an example of how to effectively rewrite a reusable component (such as a web poll) without using components.
Ryan, I don’t have a problem with namespaces. If you look at my Ruby projects I use namespaces all the time. I however don’t use them with my models and controllers in Rails because it tends to cause problems and I find I can keep everything organized anyway.
Components people, Enjoy them if you’d like. I still expect them to come out. Most of the core team describes it as a half written solution.
You’re smoking crack if you think components or pagination is broken.
This is why you should lock your apps to a specific rails version people…don’t risk your app breaking by using whatever is installed on your server.
hey this article is great. thx
what’s the problem with find_all and find_first? this is a nice shortcut. are dynamic finders ex. find_all_by_name/ find_first_by_name deprecated? bin verwirrt…