Are you backup/restore procedures good enough?

So, my MacBook crashed yesterday. It didn’t really crash, just that it went black after logging in. Although I have a suspect, I won’t name it here because I don’t want to start a flame war or something. The issue is that the partition has became so corrupt that it couldn’t fix it with the Disk Utility. The only option was to do an rsync backup from the single user mode to an external USB drive, which took ages to do. Hint: to enter single user mode hold Cmd + S when powering on your MacBook. Strike one.

I do have a TimeMachine backup at home, but the laptop didn’t stay turned on long enough to backup properly. The last good backup was more than 2 months old. I found myself in a bad situation. The other thing that happened is that my brother’s laptop also stopped working the day before. His issue had something to do with the nVidia drivers on ubuntu. Good to see that nothing has changed since I last used linux and nVidia together 4 years ago. Being stupid as I am, I overwrote the macOS usb with the ubuntu image. All was fine with my MacBook, what could go wrong. Strike two.

Something happened during the restore procedure and managed to mess up the restore partition. The only option was going back to Mavericks that came installed on the MacBook when I bought it. I wasn’t planning on doing that. Strike three.

I managed to back up everything, deleted the system partition, and did a fresh install. After waiting for the macOS installer to download on my wife’s laptop, for at least 2 more hours. A day well spent, no person alive would say. But I did learn a few lessons though.

Have a backup (encrypted if you handle work/client/sensitive) stuff. It’s best to have at least 2 places with backed up data, using two different backing up solutions. TimeMachine and Carbon Copy Cloner work awesome together. You can always count on something going wrong.

Use cloud storage for the “important stuff”. Dropbox, Google Drive, iCloud, there are endless affordable solutions that all do the same thing.  They keep your valuables safe if a crisis happens. Have these things on your 2 backup locations as well, you can never know…

Have a fresh usb (or cd/dvd) installer of the OS you are currently using. I had this, 30 minutes before my computer crashed, I overwrote it, Murphy’s law in action. You got one over on me mr. Murphy, well played sir.

Having procedures like these won’t prevent situations like the one happened to me yesterday from happening. But they will surely reduce the stress caused by the situation itself. I couldn’t check if the drive was ok before backing it up and deleting partitions. Backup with rsync took 6 hours, maybe even more. If the MacBook was broken, it was at least a 4 to 5 days waiting period to get it serviced. I would be OK with this if it was holiday season, but it isn’t, and I have work to do. I could buy a new one, have it delivered the next day. I could even drive to the store and pick it up myself, but why buy a new one if the old one isn’t broken. What to restore on that machine, I have unreleased stuff that isn’t in the cloud yet? Stress levels were pretty high.

In the ideal case, I’d have a backup from the day/night before and it would take me 10 minutes to decide it’s worth killing the machine and starting fresh. The os installs in 15-20 minutes, I can restore the apps/settings from the backup, or even do a full TimeMachine restore. With an external USB 3.0 drive, it would be quite fast. I could have done some productive work yesterday. Instead I spent the day staring into rsync output, hoping it will finish soon. I like the experience though, because I’ve became sloppy, and this is a fair warning to what could have happened if the SSD decided to stop working. I was lucky that I only lost a day of my life, but I learned a valuable lesson. I hope that you can learn from my mistake.

Doing new things is hard, choose your hard

In my last post I touched on the topic of quitting, and how easy it is to take the easy path instead of the hard one and quit. Most of us quit all the time, big and small things alike. When things get a little tough, it’s really easy to drop back to a place where you feel comfortable. And while we often quit, we rarely understand the consequences of that act before it’s too late.

When was the last time that you were assigned with something you’ve never done before and it seemed easy and straightforward? If I had to guess, the answer is never. New things are hard to us for a reason, we didn’t create any patterns around the process yet. Even if it’s something that you’ve enjoyed doing in the past, it takes you time to get accustomed to it in a different environment.

Maybe this is a filter of some kind, because people who persist in their efforts are the ones you hear or read about. We all have our struggles in life, the only thing that differs is will you give up or continue fighting, will you take the easy road, or the hard road. Just bear in mind that the easy road can and probably will be harder for you in the long run.

People have different learning patterns, and different backgrounds. While new associations in our mind are easy to create, it sometimes takes time to link everything together, or to figure it out. That process is hard. If you ever tried to learn a foreign language you’ve encountered it, along another issue, you need to use the language to learn it.

The best way that I’ve experienced is using what you’ve learned from day one, it will be hard for a while, but much easier in the long run. Yes, you will go full Tarzan mode with constructs that translate to “I want go food” or something similarly funny.
The trick is not to be afraid or ashamed while you are learning something new, otherwise it wouldn’t be hard for you to do it. If you are surrounded with the right kind of people, they will encourage you and help you, even dedicate significant amounts of time into helping you, because that is something they also care about.

Same thing goes with learning new computer languages, or programming paradigms. Yes it’s hard to learn Object-Oriented programming, it is also hard to learn Functional programming. While I’m on the subject, it’s pretty hard to learn testing, and that is just the high level stuff. Everyone one of us has been an apprentice at one point or another.

Sometimes I am still an apprentice in some new technology that I’m interested in. You will always have new stuff to learn, it will (probably) be hard, maybe you even won’t succeed, but are you willing to immediately give up the benefits you could reap for your whole lifetime just because you need to suffer for a day, or a week? I’m not, when something gets too easy for me, I just have to find something new that will push me even harder in the direction I’m moving to. It’s pretty easy to figure out that most of the things that you appreciate in your life are hard. Raising children is hard, running a business is hard, competing in sports is hard, sometimes even breathing seems hard. Do you really want to spend your whole life as a couch potato, watching TV and not achieving what you might if you just put in some effort?

I’ll end this with a nice quote from a three-time Tour de France winner Greg LeMond: “It never gets easier, you just go faster.”

It's really easy to quit

I remember when I was in my late teens, although I rode on the bicycle around a lot, I never did anything longer than a few kilometres in one go. I had an old steel mountain bicycle, heavy as hell, but it was enough for me.

Once I decided to visit a friend who lived about 25km away, and decided to bike there. It was one of the worst experiences in my life. I barely managed to do it, having cramped muscles for days after that, also I went back home by train, bicycle with me.

Nowadays, after 15+ years I can successfully ride for 100 and even more kilometres, probably using less energy than ever before. I admit that I have better bike(s) now, but that is not the point. 15 years ago I just gave up on the spot, as soon as it got hard. Quitting was easy, except for the next couple of days when I could barely walk, but the act of quitting seemed pretty liberating. You just run away and don’t look back.

A few months ago I went on a ride alone, and after 2 pretty hard rides in the two days preceding the current ride, my legs were pretty empty in the start. And I had 4 climbs on the route. I almost gave up after the first climb, but then something hit me. The pain you are feeling now, just means that when you go out tomorrow, or the next day, you will be even stronger than you are today.

By putting constant effort, especially when you don’t feel like it, you will gradually improve. I like to measure my cycling performance a lot, because if you can measure something, you can improve it. I’m far from being a pro, and I’m pretty far from competitive racing, excluding one with myself. The bike pulled me out of a really bad place I had put myself into. I’ve lost 40 kilo over 3 years on the bike, and now I’m feeling better than ever.

I’m using a cycling analogy here, because it’s the easiest thing that comes to mind here. But the real story I want to tell you is about yourself. You are the one that quits when it gets hard, I know it, I was the same, quitting when things get tough. Requiring constant and immediate feedback is something people cherish a lot, but the things that give you immediate feedback are mostly bad for you.

What I’m trying to point out here is that you are the only person responsible for your own destiny. If you are willing to go through life as a quitter, giving up as soon as it gets a bit harder than usual, you will become weaker and weaker. By not challenging yourself with new things every day you slowly degrade.

There is a pretty common saying that businesses which are not growing are falling apart. You could be stagnating, but given that everyone else around you is growing, you might as well be in the red, it is mostly the same. And this relates to people really well. Just think about your parents, or grandparents. Some of them know how to use a computer, some are pretty proficient with it, and some can’t even use a microwave.

Back to you, if you are a programmer, there was a time in your life when the only thing you knew how to code was ‘Hello World!’ in some language that you don’t use anymore. Why did you continue through the hardships of learning other languages, patterns, algorithms, just to call it quits today?

I hopefully have a couple of decades left to do something productive, can’t even imagine the language I’ll maybe be writing code in before I choose to retire. I might not even be writing code then, but I’m not afraid of it at all. Life is a constant change, and by accepting it, and going with it, you will find yourself being a better person than you were before.

One person told me a pretty resonating thing, and it stuck in my head. If I didn't challenge myself to do hard things, I would still be stuck doing a shitty job that I did 3 years ago. And it’s true for me too, on different levels. I now have a really great job, more energy and a lot more chance to hopefully get to see and play with my grandchildren in 20+ years. And I don’t really care about what will happen tomorrow, because I know I will deal with it.

P.S.

Exercising is really good for you, and you must start immediately if you want to play with your grand children, even great-grandchildren if you are really lucky. I know people who can’t even go out and play with their own children because they just called it quits on their own health. It’s really sad, but I don’t think they will even live to see their grandchildren. Tech jobs are pretty sedentary ones, and I know how easy it is to stuff yourself with fast food, while working 12+ hour days, getting bigger and bigger. If you are in this situation and don’t know where to start, there is a great book by Joe Kutner called The Healthy Programmer. If you need more help don’t be afraid to contact me. I’ll be glad to help you get on your way to feeling and doing better.

Don't (only) focus on the code

Every developer aspires to create great things, but often the most important issue is not just the quality of your code, but many other and obscure things that are setting you back from achieving your and your company’s goals.

You should write good, well tested code, which doesn’t have to be perfect, but merely good enough. I know that some of the purists will get mad but that is often the case. As the saying goes, Perfect is the enemy of good enough. I won’t go into the quality of the code anymore, because I believe you, as most of the programmers do, write good enough code. What you should focus on is something completely different.

There are three things that you can do while working for a company or consulting for a client:

  • Create value
  • Reduce expenses
  • Both of the above

Ultimately I want you to always think of the ROI (Return On Investment), for either your employer, your client, or yourself in the end. If you steer away from that focal point, and start procrastinating on delivering the product, because the code, design, or copy is not perfect, you will never ship it. Also, if you are not embarrassed by your first release, you have shipped too late.

Now, think long and hard, what situations call for further improving the quality of your code to stick them in the three categories mentioned above? Testing and refactoring bad code will improve future maintainability, which reduces expenses in the long run. Optimising for performance and making the application faster can bring you more clients and earn more money. Optimising workflows will cut the time needed for the end-user to finish a unit of work faster, which reduces expenses per unit of work, allowing them to do more in the same amount of time, or to work less.

Automation is a nice thing to have, but unnecessary in the beginning. If the product that you are creating succeeds, and you start spending a lot of time on processes that should be automated, please automate them, and delegate the execution to someone else. But don’t do it before it really starts to hurt, because you are wasting your (and the company’s) precious time.

Understanding how and why the software does what it does should be the main thing for you to learn about. I agree that you can be some level III programmer in an enterprise behemoth, really detached from the process, being fed with your daily or weekly tasks through some project planning tool and not really knowing how the sausage is made. Maybe you are one of the Dark Matter Programmers, and aren’t really ambitious to move up, and that is also OK. I know people that are in the same situation as you are, happy with the work they are doing. Although I consider this approach highly insecure and uncertain for the long run, it is practical for the present, for them.

If you are focusing on the process, and eliminating the obstacles to reach one of the three points mentioned above (create value, cut expenses, both of them), then your software will be better in the long run. In that process you stop being just a programmer that is easily replaceable, and start being a true business consultant, with a unique set of skills.

As an example, there is a process that each end user has to do to make one widget. It includes going through 10 different screens, and entering a dozen parameters on each screen to produce the widget. Creating any type of widget generally takes 10 minutes Although the company makes different types of widgets, let’s say that one widget accounts for 80% of the sales, and all others for only 20%. Optimising the code in this situation does nothing, because the code has to produce a variety of widgets, and unless it’s really messed up, you should leave it alone.

Optimising the process on the other hand is something completely different. Especially if we have a situation like I mentioned above. I really love the Pareto principle, and try to use it all the time, applying it to any situation will allow you to focus on the stuff that really maters and ignore/drop the stuff that doesn’t.

How do we apply it to the above example? Let’s call the widget that accounts for 80% of the sales The Golden Goose. All widgets have around 100 properties you can set while creating them, but 95 of them are the same for each Golden Goose. So why bother entering and checking each one for a process that happens 80% of the time. Optimising the process from 10 screens and 100 parameters that takes at least 10 minutes and allows for a lot of human error, to one screen and 5 parameters, which reduces the widget preparation time to only one minute will drastically increase the user productivity, allow them to push out more widgets in the same time.

By focusing on the business and not only on the task at hand, you will stand out among your peers. There is no difference whether you are an employee, a freelancer or a consultant, your customers will generally have more respect for someone who looks at the bigger picture, and speaks their language. You can do yourself a big favour and read a couple of business books. It is a very big chance that you work for one, so why not invest a couple of hours in understanding how businesses work. It is a very small chance that those hours are spent in vain. If you don’t know there to start, The Personal MBA by Josh Kaufman is really great, and I can’t recommend it more.

The LinkedIn experiment

If you are an engineer you probably don’t see much use from LinkedIn as a service. It is full of recruiters, who can be very annoying from time to time. You can choose to link people you have worked with, went to school with, or know from one source or another. Aside from this fact, I didn’t see that much use in LinkedIn. So I decided to run a small experiment. No, I won’t give them access to my email or something stupid like that, but I’ll do my best to use the site as it was intended to.

I’m not really hoping to gain anything from it, aside from maybe a new connection or two. I know I’ll get spammed like there is no tomorrow, and that was one of the reasons I killed my profile a couple of years ago. But this time I mean business.

I’ll do my best to post updates, link interesting articles, fill my profile with everything I can, and even leave a review or two. I’ve already started doing some of those things, and I’ll follow the plan at least till fall.

As I’ve previously mentioned, I don’t want anything. I’m not looking forward to getting spammed by recruiters, and I probably won’t be looking for new projects soon. I just want to see what can be done with it. I’m always open to finding new acquaintances and similar minded people. I was also considering joining (or starting) a mastermind group, and maybe LinkedIn can provide some help with that.

If I don’t get anything out of this small experiment, and I sincerely doubt that I won’t, I believe it will be a small amount of time well spent. I’ll surely write a post about my results in a couple of months.

Understanding the Ember run loop

All of the Ember.js internal code, and most of the stuff you write while creating an Ember.js app runs with the help of the run loop. It is used to batch, order and reorder jobs in a way that is optimised for efficiency. I didn’t notice it’s existence before I ran into problems with the JavaScript setTimeout function callbacks and when manually running async calls to the API.

How Ember run loop works

If you’ve read any of the productivity books out there, they all state that batching similar jobs is the key to success. Ember run loop works in a similar way. By running same or similar jobs at the same time, the browser doesn’t have to skip around from task to task, which eases the burden on it, and if you change the same property a couple of times in the same loop cycle, it will only have to process the last change.

Jobs or tasks are scheduled into different queues, and the queues are processed by priority until they are empty.

Queues

Ember run loop consists of six queues

Ember.run.queues
// => ["sync", "actions", "routerTransitions", "render", "afterRender", "destroy"]

Each one of these queues is responsible for some jobs batch that runs inside of it.

  • sync contains the binding synchronisation
  • actions is the general work queue, and the one that generally handles promises.
  • routerTranisitions contains transition jobs in the router
  • render contains the jobs that are associated with rendering the page and updating the DOM
  • afterRender runs after the DOM is complete, after all the render jobs have been executed. This is the perfect place if you want to update the DOM after it has been rendered.
  • destroy is responsible for destroying everything other objects or jobs have scheduled to destroy.

Testing

Ember run loop is really important when running tests in Ember. Ember raises errors in testing mode when we try to schedule work without the run loop.

When should you use the run loop

Strictly speaking, all non Ember api code should be wrapped inside an Ember run loop. That includes:

  • AJAX callbacks
  • DOM updates and event callbacks
  • Websocket callbacks
  • setTimeout and setInterval callbacks
  • postMessage and messageChannel event handlers

Be sure to wrap the callback body in the ember run loop and not the whole invocation. For example:

var controller = this;
socket.on('channel', function (data) {
  Ember.run(controller, function() {
    console.log(data);
    this.set(‘message’, data.message);
  });
});

This fires an Ember run loop after the callback is executed, and the callback code will be executed at exactly the right moment.

Domain switch

If you are a somewhat regular reader, you have probably noticed that I’ve changed the domain name from babinho.net to berislavbabic.com. Maybe you didn’t notice it at all, kudos for that, because you have been redirected automatically. There were a few reasons for my decision, and I’ll try to sum it here. I won’t go much into details of how to do it, because you already have a lot of information on the Internet covering it. First to explain the babinho moniker. I’ve been using it for a lot of time now. It’s a nickname that dates back to the year 2000, and stems from the obsession with Brazilian football players way back then, when we all had similar nicknames. And mine just stuck around. I wanted to retire it for a long time already, but the more you are invested in something, the harder is it to move away from it. I decided to follow the advice given primarily by John Sonmez in his blogging course, but it is also suggested in many other places, and used by a lot of people I’m following and consider to be internet famous, at least in the small niche that I’m following, e.g. Nathan Barry. As this is a personal technical blog, I decided to go with my name and not some SEO optimised domain name. I believe that personal branding is the corner-stone for each developer, and something everyone, in the tech world or not, should work on as much as possible. There is no better way for you to stand behind your work by stating your name loud and clear. It is professional to the core, and gains you more respect than some childish moniker. It is the scariest thing you can do, because if you make a blunder people will know. But don’t obsess with it, because people rarely or even never remember other people’s blunders. And they will appreciate you more for trying and failing, than for not trying at all. I know that I stood behind that moniker for a really long time, and it has defined my work and sometimes my hobbies. I was not ashamed of my real name, but I just decided not to stand behind it. Going by a nickname was cool and hip, and somewhat unprofessional. Although I’m not saying you shouldn’t use some kind of an alias, especially if you are not allowed/afraid to write because of some repercussions (please do yourself a favour and change the job or the place you live as soon as possible), I am saying that you should use your own name when you engage in technical writing. If you are considering to write or are already writing about really controversial and dangerous stuff, then do everything needed to protect your identity, and be as anonymous as possible. I won’t go into details on how to do that, but there are many privacy oriented websites, so you just have to look around.

On continuous improvement

It is really hard starting something new. Just consider the first time you sat down at the computer to write a “Hello World!” program. Following the tutorial or whatever, you were able to copy/paste or type the code into some IDE or a REPL environment and run it. Then you decided to create “an application” and it was nothing like that Hello World example. Maybe you saw the video on How to create a blog in 15 minutes, and got hooked to this fancy new Ruby on Rails thing like I have. Regardless of the way you started, there is one constant in everything that you do.

If you do something consistently over a longer period of time, you will eventually get really good at it.

Consider blogging, or technical writing for example. Unless you were some kind of a teen writing prodigy, you can’t write that well. Especially if the school system you were a part of didn’t encourage creative writing. I struggled with essays and general writing throughout my school years. And I never thought that writing was a skill that everyone should have. After almost 6 years of on and off blogging, I believe writing to be a really necessary skill, and it really changes the way you express your self, and the way you convey ideas to other people.

Looking back at my posts from 2009, I can’t stop being sad for myself, because of the bad grammar, sentence construction, and even the notion of conveying ideas to people. But it got better over time. I used to struggle when writing 200-300 words in a blog post, and now a 500+ word blog post almost comes naturally.

Gradual improvement is a great thing, and if you hone your skill consistently, you will become an expert in what you do. I know I’m far away from being the next Seth Godin when it comes to writing, but I can try to improve with each post I write, and I can create a habit of writing every day.

You can do the same, choose a skill you want to improve, don’t set any goals or anything, just do it. If it’s writing, make a calendar entry each day and tell yourself to write e.g. 500 words that day. It can even be 100 words, creating a good habit is what matters most, not the amount of doing something.

Don’t set your goals too high, because you will never accomplish them, and you will loose the taste of all those small wins that come when you do get good at something, and realise that you have done something worthy.

There is a great app that I use, and it’s called Commit, and it is probably the best thing I could have done for me. This app, in addition to the Tiny Habits method by B.J. Fogg, was the cornerstone in most of my work.

It is hard to force yourself to sit down and write a 2000+ words blog post, but it is pretty easy to sit down and write 500 words. If you struggle with 500, start with 100. It won’t take you more than a couple of minutes accomplishing that goal, and if you really like what you are writing about, you can always continue. It’s the sitting down (or standing up at a desk) and starting that counts. Make that your daily habit.

You can always do more than the minimum, but set a realistic minimum that you can do each day. And your skills will improve. Of course, they will improve faster if you do it more, but don’t overdo it, because if you burn out, it will be really hard to start again.

Issue with Rails's restrict_with_exception and counter_cache

When building Rails applications, a lot of focus goes into optimisation. One of those optimizations is using Rails counter_cache columns. The reasoning behind it is simple, you have a relation e.g. Post to Comments and you want to display the comments count for each post. One option is to always count the comments for each post with something like @post.comments.count of course, this is a really expensive operation, and if you are displaying more than one post on the page, it will cause an N+1 issue. Also going to the database just to count how many rows a relation has, isn’t really the best idea.

Luckily Rails has its own optimisation, called counter_cache. It is very simple to include in the model, and Rails manages all of the magic for you behind the scenes. Below is the example of Post and the cached comments count. The only prerequisite that you have to do, is to add a comments_count integer column, with default value of 0.

#in a migration
def change
  add_column :posts, :comments_count, :integer, default: 0
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post, counter_cache: true
end

This way, via the Rails Magic™, you will get the count column incremented whenever a new comment is posted. And decremented when a comment is destroyed (if you support such a thing). Now you don’t have to count all of the comments when showing the number next to the post, which will be a pretty big performance boost (relatively speaking).

That is the first part of the equation, as the title clearly states this post has something to do about restrict_with_exception. That is the dependency management type, which disallows you to destroy a record that has child records, with that orphaning those records, and creating database inconsistencies. In our case, a post with comments.

We have to modify the Post class to accomplish this:

class Post < ActiveRecord::Base
  has_many :comments, dependent: :restrict_with_exception
end

Now every time you call destroy on a Post model that has comments, Rails won’t let you do that, and it will raise an exception, which is the desired behaviour.

Now, we avoid rails and use regular SQL when the situation needs us to. Let’s say moving comments from one post to another. It can be done with

@post.comments.each do |comment|
  comment.update_attributes(post_id: @new_post.id)
end

But for a post with a lot of comments this operation can be too slow. Moving comments with a sql update is much easier and faster way to accomplish the same thing, but not without it’s own pitfalls. @post.comments.update_all(post_id: @new_post.id) will update your comments and set them to the new post, and you will probably want to refresh the counter_cache on the @new_post, so you have to do something like this Post.reset_counters(@new_post.id, :comments).

Now if you forget doing the same thing on the old post, and just try to destroy it, you will fins yourself chasing ghosts. Rails somehow takes the counter cache column as an authority, before even looking if there are associated records there. This is a cool performance hack, and by going only through Rails, and not pure SQL, this situation wouldn’t happen at all.

Sometimes we can’t or don’t need Rails call backs and validations, just to transfer the ownership from one model to another. Then weird things start to happen, and you don’t know why, so you lose a day debugging what should be a simple thing.

Dynamic components in Ember.js

When building Ember.js apps you will try to avoid code duplication as much as possible. One of the ways of doing that is using Ember components. Components are small, reusable pieces of code, that share a common functionality. For example, you can have a component that shows a user’s Twitter feed, that receives the twitter handle as a parameter.

Components are the new hotness and the way to go with Ember.js 2.0 and they are also being introduced and used in HTML5. Ember components are closely built to adhere to the W3C specification so they should be compatible when the component adoption increases.

Sometimes you want to render a different component in the same place, for example a user’s image and contact info, which can be different for a person and an organisation. So to avoid ugly conditionals in handlebars code there is an option to show components dynamically with the convenient component helper.

You won’t avoid having those conditionals of course, but you won’t have to put them in your handlebars templates, which should be as logic-less as possible. They can reside at the model level, as a computed property. I will simplify this even further and use an example where we will receive the value from our API.

We will be using a simple polymorphic relationship in our API and values returned from ownerType will be “user” and “company” for this example.

Of course we want to show different data for the user and the company, but because we are showing them in the same place, we would have to use a conditional in handlebars to show them. And or model (or controller) should return the isUser boolean. This approach will make future code maintenance a nightmare.

// app/models/owner.js
import DS from 'ember-data';
import Ember from 'ember';

export default DS.Model.Extend({
  name: DS.attr('string'),
  ownerType: DS.attr('string'),
  // ...
  isUser: Ember.computed.equal('ownerType', 'User'),
  // ...
});
{{#if model.isUser}}
  {{owner/user-widget owner=model}}
{{else}}
  {{owner/company-widget owner=model}}
{{/if}}

As you can see, this conditional isn’t really the best one imaginable. If we add another ownerType possibility, we will have to add an additional component (which is the only thing we should be doing), add another boolean on the Owner model, and make the conditional above even more complex than it is. No one probably wants to be remembered by code like this:

{{#if model.isUser}}
  {{owner/user-widget owner=model}}
{{else}}
  {{#if model.isOrganisation}}
    {{owner/organisation-widget owner=model}}
  {{else}}
    {{owner/company-widget owner=model}}
  {{/if}
{{/if}}

There clearly must be a better and cleaner approach. Ember component helper comes to the rescue. And with some clean coding we can avoid all of the conditionals mentioned here.

// app/models/user.js
// ... 
   widgetComponentName: Ember.computed('ownerType', function() {
     return `owner/${this.get('ownerType').toLowerCase()}-widget`;
   });
// ...

This way, the model returns a convenient and usable string when we get the displayComponentName property from it. Now we can use this and have the cleanest possible handlebars template:

{{component model.widgetComponentName owner=model}}

Component helper will resolve the correct component and render it. If a new owner type pops up, the only thing we need to change is to add the widget component for that owner, which is also a great example of separation of concerns, and we are reducing code churn a lot. To reduce the code duplication and complexity you can also take use inheritance to combine similar functionality under one object, and extend it with specific code for each object. I’ve written a blog post about it called Simple Inheritance with Ember.js that you should definitely check out.