Join Kevin Skoglund for an in-depth discussion in this video Traversing a rich association, part of Ruby on Rails 4 Essential Training.
In the last movie, we created a rich join between admin users and sections. While we gain the ability to add complexity in the form of other attributes and methods in our model, we lost something at the same time. We now have to go through an extra step to get from one side of the association to the other. For example, in our has and belongs to mini join, the simple version, if we want to know all admin users who can edit a page, then we can just request the array of editors from the page. It will return a list of the admin users who are considered editors of this page.
But in a rich join, we can't just ask for a sections editors because there's no direct relationship between a section and an admin user. There's a model in between now. We can still do it we just have to take an extra step and go through each section edit in order to look up its editor. What we really want is a way to reach across the join easily. To be able to access the editors by just calling section.editors. It's clearly possible because the has them belongs to many joined does it. It's just a question of telling active record about this relationship so that it can modify the SQL it writes.
And treat this rich join like a simple join in some cases. To do that, we use, has_many :through. Has_many :through will allow reaching across a rich join to treat it like a has and belongs to me join. The first step is going to be defining a functional rich join first. Get that working. And then once that's working, you can define has_many :through. For example, in our application, where we have Admin User and Section. Our rich join is, admin user has many section edits, that's the relationship between admin user and our join table.
Now we need a new relationship between admin user and sections, that's the table that sits on the other side of that join. We're reaching across the join, from admin user to sections, and we're going to do it by going through, section edits. It's very similar to defining has belongs to many, the only difference is that we're telling it this is a rich table that you're reaching across. It's not just a simple joined table, and that's going to change the way Rails treats it. On the other side of our many to many relationship, we'll have section has many section edits, so for has many through, we would have section has many admin users.
Through section edits. And just like the other associations we've seen, make sure that you always define both sides of the relationship. Let's try it. Let's start by going into admin user. And we can see we have has many section edits already. Right below that, we're now going to make a relationship between admin_users, so that it has_many :sections. And it does have many sections, if we go through section edits to get there. Let's save that file. Now let's open up the section, and the section has many section edits.
Now, we need to add a new relationship between section and admin users. That would go through section edits. Now just like before, I think instead of using admin users, I'm going to stick to this idea of editors. Which means that we also need to configure the class name here, so that rails know what to look for. So admin user is going to be the class. So. A section has many editors if you go through section edits and look for the table that belongs to the class AdminUser. So, save that file.
Now we don't need to make any changes to Section edit. Section Edit already has a relationship. This belongs to a relationship provides everything that it needs to know about the join between editor and section. This is really about the relationship between the section and the admin user. That's the relationship that we're creating, we just happen to be going through the section edits table to get there. All right, let's save both of those and then let's try it out. Let's switch over to our command line. Make sure your in the root of your Rails application. And relaunch your Rails console to make sure that those new class definitions are loaded.
And I'll do me admin user find one. Alright. So now, me.sections will tell me the sections that are mine. You can examine the SQL that it generates. You will see that it has an enter join in there with section edits that it's using to traverse that rich association. That's the has many thought. we can go from the other side, we'll have section equals Section dot find one and then let's ask for Section dot editors.
We're looking through the edits to find out who the editors are who made those edits. That is similar to what would happen if we went through the join ourselves and said, all right, every section to get section edits. And then map those, so that each section edit brings up its section editor. Let's try, that's the long way and you can see that we get some more results. Not only is the first way shorter and more convenient but it also allows rails to write more efficient SQL to accomplish this goal. Now, it is a lot like having a has and belongs to many relationship between the two, but it's not exactly the same.
And here's one main reason why. Let's say that I had section.editors and I wanted to add a new editor that was name was bob. Right, I could do that and it would let me add bob as an editor and it would create the join in between, just like a has and belongs to many. But the thing is that now my section edits in the middle. Has attributes, it has columns and data that it's expecting. Such as our summary column. And this would not allow me to put that information in. We'd just be working with the two outside elements, and not with the joined table and the model in between.
That would especially create a problem for us, if that section edit's summary column was required, before we would allow it to be saved to the data base. So when you're creating new section edits you probably want to do it the way we did it in the last movie. When we were just working with the existing information, and you want to traverse across that rich join, then has many through is going to be the best way to do it.
- Why use Ruby on Rails?
- Installing Ruby on Rails on Mac and Windows
- Rendering templates and redirecting requests
- Generating and running database migrations
- Creating, updating, and deleting records
- Understanding association types
- Using layouts, partials, and view helpers
- Incorporating assets using asset pipeline
- Validating form data
- Authenticating users and managing user access
- Architecting RESTful applications
- Debugging and error handing
Skill Level Beginner
1. What Is Ruby on Rails?
2. Installing Ruby on Rails on a Mac
3. Installing Ruby on Rails on a Windows Machine
4. Getting Started
5. Controllers, Views, and Dynamic Content
6. Databases and Migrations
7. Models, ActiveRecord, and ActiveRelation
9. Controllers and CRUD
10. Layouts, Partials, and View Helpers
13. Data Validation
14. User Authentication
15. Improving the Simple CMS
16. REST and RESTful Routes
17. Debugging and Error Handling
18. Introducing More Advanced Topics
Next steps1m 40s
- Mark as unwatched
- Mark all as unwatched
Are you sure you want to mark all the videos in this course as unwatched?
Take notes with your new membership!
Type in the entry box, then click Enter to save your note.
1:30Press on any video thumbnail to jump immediately to the timecode shown.