 All right. Hello. Hi, everyone. My name is Ted. You can find me online in most places as Drenmi. I work for Tinkerbox, which is a local Ruby on Rails agency. And I'm here to deliver the five random Ruby tips of this meetup. So for this time, I actually picked a theme, so I sort of broke my own rule there for five random Ruby tips. Recently, one of our junior developers, Daniel, started a daily Ruby Cata session, which brought me back to a website which I registered for in, I think, 2013. One thing this website does is when you sign up, you need to list your skills. And for reasons that are lost to me now, I listed my skill as hiding things. So the idea now is to help anyone who has to work with me by presenting five tips on finding things. And more specifically, finding things with ActiveRecord. Because the reality is that most of us doing Ruby full-time need to work with Rails. And so we need to work with ActiveRecord. But I like to point out that there's also a great gem called SQL. So if you have the time to work on a pet project or something where you want to try something new, I definitely recommend trying that out. So the first tip is a new method in ActiveRecord 5. And the way you know if you're using ActiveRecord 5 is if you're using Rails 5, then you're using it. So there's a new method called left joins. And if you imagine an extremely simple domain model where you have a company that has zero or more users and the user belongs to the company, and you want to query out companies based on some property of the users, you first need to join the user's table. But if you're familiar with SQL, the problem here is that once you do join, any company that doesn't have any user will be left out from the results. So say that you want to list all companies that don't have a billing contact. You will miss out on all the companies that don't have any users at all, which you might have actually wanted in your result. So you can see this is the SQL generated by using just joins. And if you use left joins, it will replace the inner join with a left outer join. And this will give you the companies without users as well in your result. The second tip is also new for ActiveRecord 5. So they actually introduced the OR method. Previously, you could only do OR by including a SQL fragment using a string with the actual SQL statement in it. And the way it works is you can chain it onto your relation, but you need to pass it another relation as the argument. You can't use an options hash like you do to where, for example. And this might look a bit clunky, but there are good reasons for this. So the reason it took so long to get this seemingly trivial feature is because once you start making more complex queries, there can be a lot of ambiguity of, like, where does this OR actually end up and how are different ORs and adds grouped together. So there were two or three pull requests made to Rails that were rejected to implement OR with the options hash until someone actually suggested that let's just do OR and you can pass it a relation. And the SQL that's generated from this looks similar to this. So it just changed the OR onto the where clause. Third tip, checking for the existence of record. I chose to include this because I see this a lot in code reviews as a chance for improvement, so I think maybe it's a method that not everyone is aware of. So frequently people need to do some guard clause or something based on the existence of some record based on query criteria. One of the common ways I see is to use where and then chain on any at the end, which works fine. Another method I see is to do a count and then check that the count is greater than zero. So the downside of these two, apart from not being super explicit, is that it will actually go and count everything. So to check if there is a single record matching your criteria, it will go and count all the records matching the criteria. So what you can do instead is to use the exists method and you can just pass it the criteria. The biggest benefit to me is that it's more explicit. I want to check if this record exists in the database. But the other nicety is that it generates a SQL query that basically short circuits itself when it finds the first record. So it only needs to go and find one of them. So the fourth tip is how you can create on-the-fly through relations using the joins method. So here I've set up another super simple domain model where you have offices having many employees and each employee has one role. So here you might not actually want a through relationship because your office might not have roles. It might not be super clear what that means. So you can actually use the joins method and you can pass it a hash like this and it will join on both these tables. So we will essentially have a on-the-fly through relationship that you can use in your query. So the generated SQL looks like this. First it will join the employees onto the offices and then it will join the roles onto the employees. And now you can query out offices based on properties of the roles of the people working there. The last and final tip is how you can merge queries with the merge method. And I think this is very powerful for the longest time. I only thought the merge method was like a poor man's concatenation thingy that you could use to merge together different scopes and still get a relation out. But that's actually not what it does at all. So here we have an even simpler domain model. We have books and the books belong to an author. And now we can do something like this. We join the author onto the book and then we select where the author is a Nobel Prize winner. And this looks fairly straightforward but you can also do it like this. All right. First it's the generated SQL. You can also do it like this. And now we might ask what is the purpose of this. This doesn't look much different from the previous version. But we must remember that this query about authors being Nobel Prize winners is very simple in this case. But in reality this query can be arbitrarily complex. So you might want to select some client based on some different complex criteria. Which means you can now contain that implementation detail inside your client's model as a scope instead of duplicating it into other places. So what merge does it actually goes and automatically merges your SQL queries together. So it merges the SQL queries not the actual results. And this is just to show that the generated SQL query by using merge is identical to the one where we hard coded the criteria inside the query. Right. So now that I told you how to find records I will give you a one non random tip how to find a job. Because we're hiring. The caveat is that we are only hiring seniors at the moment. We had tons of applications for junior developers and found some really good people. But now we really need more seniors as well. So the reason you should join is because we care a lot about code in thinker box. And in fact test coverage is one of our KPIs. So we currently have 98 percent test coverage on our client projects. We also believe in giving back which is why one of our KPIs is community outreach. So I'm actually racking up some points as well while I'm here. We also work hard and we play harder. We play a lot of football. We play board games, rock band. Anything that can be played is played. If this sounds interesting and you think that you're a senior level developer then hop on to the website tinkerbox.com.sg. Click into the careers section and then you can send us an application from there.