Skip to main content

Refactoring with the Null Object Pattern Discussion

General • Asked by Chris Oliver

One thing to watch out for with NullObjects is Relations. Rails recently introduced a Relation#none method which will help in these cases. Imagine a Post has_many Comments, you'd want to create a NullObject for the Post and create a method called comments which returned Comment.none

See for more information.

Yes, the none method is super helpful for situations like that. I'm really glad they added it.

This is definitely more robust but is implicitly less expressive (in my opinion). My code can tend to suffer from IF-itis and maintainability down the road so this is useful as a pattern to consider when re-factoring. Thanks!

Definitely. You can use this a bit too early and it just is more painful than anything. The example of the navigation is bad because right now, I'd rather have the if statement, but in the future as it gets way more complex, null objects would make more sense.

There's certainly a balance to find when applying this (like any pattern).

This is super helpful man :)

Awesome, glad you liked it! :) Definitely want to cover more of these design patterns and their practical uses.

That'd be really awesome! I'd love to see more videos covering that :) I think it's really an area that's not touched in much (if any) other screencasts.

This is really cool. I am in a situation where I have many user roles and would love to be able to serve a navbar for each role. Yay! Thanks. Also in my views I have used the decorator pattern like `user_decorator.rb` and then made methods with a method `link_to_project` and then in that method done something like `object.project.present? ? h.link_to(, project_path(object.project)) : ""` or, similar to your example in the video.

`comment_decorator.rb` with a method called `link_to_user` with `object.user.present? ? h.link_to(, user_path(object.user)) : "Anonymous"`

I have done this everywhere so I might take the null object pattern to deal with the nav first then once I get familiar try and tackle all my decorator stuff.

A combination of decorators and the null object pattern can go together quite well. Curious to hear how it goes for you!

This is awesome! I'm glad you did a screencast on this, the talk from Sandi was just way too good not to share, and proliferate those ideas!

I agree! It was also awesome to meet you in person Jared!

It was awesome meeting you as well Chris! I look forward to next years RailsConf!

@excid3:disqus awesome episode! What are your thoughts on doing a screencast covering payments? I'm interested in seeing how paywalls are set up. Is it simple as using something like pundit? I've tried searching online for resources and have come up empty.

Great episode Chris. FYI, your link to source code is missing. Found it on github, looks like a missing link.

Thanks! Fixed that link.

Really helpful, thanks for screencast

Really cool video, the null object pattern is definitely a cleaner way than using :try.
I'm trying to use it in combination with the globalize gem, and get stuck when I want to force the locale. Per example, the standard use is article.title and when I want to force the language I do article.title(:en). In this particular case, if no article is found, method is called and generates a wrong number of arguments given (1 for 0) error. Do you have any hint on this ?

simply use def name(*) 'name'; end did the trick

Perfect! I was going to say, it sounds like your title method or something on the MissingArticle isn't accepting the number of arguments that the ActiveRecord model is. Glad you figured it out! :)

Chris, this one is awesome. I don't know how I missed this episode before, but I'm glad I just ran into it. Would be amazing to see a screencast where you collect the most important patterns/tricks. I guess there are a bunch of guys including me who don't even know about the existence of them, so you shouldn't even explain everything just let us know about it and mention some resources to read.

Something very interesting about this code is that with that "def user" you're overriding the definition of the parent class (ActiveRecord::Base) for the #user method, when actually there is none! :D Because of the way Active Record works, the #user method is generated at runtime. So, when you call super inside it, you're actually triggering that definition.

Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 20,000+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.