Learn how to organize and define Ruby classes to make object-oriented programming easy with Sinatra. Discover a useful Ruby technique to automatically include all files in a directory into a Sinatra application.
- [Speaker] I this chapter, I want to go over a few useful techniques that I think might help you when you work with Sinatra. And the first of these is how to work with Ruby Classes effectively in Sinatra. Ruby Classes are a great way for us to bundle up Logic into a discreet object, so we can then instantiate those objects and work with them. Let me demonstrate how we can work with those in the Sinatra project. So I'm going to create a new directory inside my explore_california folder, I'm going to do that by control clicking and choosing new folder, and I'm going to call it classes.
If you're family with Ruby on Rails, you might want to call it models, or you could just call it something else, secluded file, something like that. Here is going to call it classes though, and inside there I'm going to control click again, I'm going to add a new file, and I'm going to call this one user.rb, the rb is important because its a Ruby file. Now inside this file, it's a perfect place to define a Ruby Class. So class, capital User, and then inside that class, let's add attribute accessor for username.
And let's add method in here, admin?, which is just going to return false. Alright so lets save that file, we've now defined a Ruby Class, we can instantiate an object of this class, we can assign and read back a username, and we can ask it whether or not it is an admin, by calling that admin? method on it. Okay, so no now that class is defined. Nothing special there, that's just basic Ruby. But how do we make use of that now in our Sinatra project? Right that's the question. We need to load in that file, the same way that we loaded in our helpers file.
So you could use require relative, and you could target this file, and tell it to go inside classes to get user.rb, but I want to show you an even better way to do it. Which is to load in all files inside that classes directory that end in .rb, no matter what files are there. If we add a new file, it'll just automatically get picked up, we won't have to remember, come back here and require it. The way we can do that is by using a bit of Ruby, Dir, with square brackets, and then inside there we're going to provide a path, I'm going to use the root path + classes, and then I'm going to use a wildcard .rb.
So that's a wildcard, very similar to what we were using with our routes, it basically tells Ruby to go and use a wildcard to match any file that ends in .rb in the classes directory. And it'll return an array from that, an array of files that match. So once we have an array, we can loop through it, loop through our array, each item in the array will be called file, and we'll just require file. That's it, that will automatically loop through our classes directory and include any file that ends in .rb. And you can use this technique for other things.
If you have other code that you want to automatically load in, all you have to do is change classes to be something else, right? Anything that you drop into that directory automatically will get loaded up for you. It's a very useful technique to have. So let's try it out and just make sure that it all worked. So how can we try this out? Let's go to our coded here, and let's a do a before filter. We learned about before filters at the end of the last chapter, we didn't actually try one, but we can do one here. User = user.new, that's that user.username = guest.
Alright, so now every single route is going to have a user object available to it, and the username is going to be set to guest by default. Alright let's save it and let's try this out. Let's create a new route where we can actually just view that, I'm going to skip down to the very bottom here, let's add one here just called /username, this is just for demonstration purposes. And what is it going to do? Well let's go into output username, lets interpellate @user.username.
Alright, so it should be able to use that object that we created, that we set to the instance variable and read back it's value. So all this will only be possible of course if we were successfully able to load in that class. Otherwise it won't know what we're talking about. So let's try it all. Let's save it, let's go over to terminal, let's launch Sinatra, we'll go into Firefox, and let's try /username. There it is username: guest. See how that works? So because we were able to work with an object here, we know that we were successfully able to load in that class file.
So our line of code here at the top did exactly what it was supposed to do.
- Installing Sinatra
- Launching the server
- Defining routes
- Using route patterns and parameters
- Redirecting requests
- Rendering dynamic templates
- Using partial templates and layouts
- Defining custom helpers