WEBVTT

1
00:00:00.000 --> 00:00:01.860
[Treehouse™: presents]

2
00:00:02.890 --> 00:00:05.410
[Quick Tips: What is a has_many :through association in Ruby on Rails with Jason Seifer]

3
00:00:05.410 --> 00:00:06.460
Hi! I'm Jason.

4
00:00:06.460 --> 00:00:08.270
In this Treehouse Quick Tip,

5
00:00:08.270 --> 00:00:11.810
we're going to talk about what a has_many through association is

6
00:00:11.810 --> 00:00:13.240
in Ruby on Rails.

7
00:00:13.710 --> 00:00:17.970
A has_many through association starts with a has_many association.

8
00:00:18.560 --> 00:00:21.640
As an example, let's say that we're a magazine publisher

9
00:00:21.640 --> 00:00:23.460
building out our website.

10
00:00:24.190 --> 00:00:27.080
We have a model for magazines and for users.

11
00:00:27.080 --> 00:00:30.620
We want to be able to show a user a list of magazines

12
00:00:30.620 --> 00:00:32.150
that they are subscribed to.

13
00:00:32.810 --> 00:00:35.720
We can do this by using something called a join table.

14
00:00:36.310 --> 00:00:40.650
A join table will keep track of the first model--in this case, the user,

15
00:00:40.650 --> 00:00:44.350
and the second model, which in this case is the magazine.

16
00:00:44.830 --> 00:00:47.470
But we can call our join model a subscription.

17
00:00:47.470 --> 00:00:50.340
Now, let's take a look at what the code looks like.

18
00:00:51.450 --> 00:00:54.600
So here's a user class and a magazine class.

19
00:00:55.180 --> 00:00:58.280
What we want to do is also create a subscription class

20
00:00:58.280 --> 00:01:01.130
which is going to be our join table.

21
00:01:01.800 --> 00:01:03.970
So let's say that we generated a subscription class.

22
00:01:03.970 --> 00:01:05.780
It would look something like this.

23
00:01:12.770 --> 00:01:17.140
Now, on the back end when we were creating our subscription class,

24
00:01:17.140 --> 00:01:20.180
the table would look something like this.

25
00:01:20.490 --> 00:01:24.290
In addition to an ID column, it would have two fields.

26
00:01:24.780 --> 00:01:29.600
One for the user ID and one for the magazine ID.

27
00:01:30.830 --> 00:01:33.770
So we're going to go ahead and pretend that that's how it is right now.

28
00:01:34.770 --> 00:01:37.900
If we wanted to set all of that up as a relationship,

29
00:01:37.900 --> 00:01:42.520
we could say that a user has many subscriptions.

30
00:01:43.610 --> 00:01:50.730
And we would also say that a magazine has many subscriptions.

31
00:01:52.830 --> 00:01:56.930
So then we set up the subscription class to say that it belongs to

32
00:01:56.930 --> 00:02:02.650
a user and it belongs to a magazine as well.

33
00:02:05.310 --> 00:02:08.030
Now that we have these associations set up,

34
00:02:08.520 --> 00:02:14.350
we can say that our user has many magazines

35
00:02:15.490 --> 00:02:18.830
through the subscriptions relationship.

36
00:02:20.160 --> 00:02:24.530
And we can also do the same thing with our magazine class.

37
00:02:30.420 --> 00:02:32.470
Well, how would you use something like this?

38
00:02:33.390 --> 00:02:35.560
Well, let's say that you we're trying to find the user.

39
00:02:37.240 --> 00:02:39.020
Grab the first user,

40
00:02:41.270 --> 00:02:43.250
and you also grab the first magazine.

41
00:02:44.190 --> 00:02:46.960
If we wanted to create a subscription,

42
00:02:46.960 --> 00:02:52.090
we could say something like user.subscriptions.create.

43
00:02:53.330 --> 00:02:55.080
And then we tell it that the magazine,

44
00:02:55.080 --> 00:02:59.670
which is an association up here on subscription,

45
00:02:59.670 --> 00:03:02.220
is this magazine that we just found.

46
00:03:03.330 --> 00:03:08.150
Now what we can do, if we really want to, is call user.magazines,

47
00:03:10.100 --> 00:03:13.620
and that would return our magazine.

48
00:03:14.460 --> 00:03:18.310
The same thing can apply to models that refer back to themselves.

49
00:03:18.310 --> 00:03:21.090
For example, let's take a site like Twitter

50
00:03:21.090 --> 00:03:25.800
and apply the same model of subscriptions but to users and followers.

51
00:03:26.180 --> 00:03:29.090
Followers are just another class of users,

52
00:03:29.090 --> 00:03:31.420
and here's what the code for that looks like.

53
00:03:32.050 --> 00:03:33.610
Now, you might be wondering what we would do

54
00:03:33.610 --> 00:03:36.730
if we wanted to have a has_many through association

55
00:03:36.730 --> 00:03:40.310
where the other end of the has_many through association

56
00:03:40.310 --> 00:03:43.290
is the same model as the original.

57
00:03:43.690 --> 00:03:48.250
Sort of like how you would do a Twitter site with users and followers.

58
00:03:48.910 --> 00:03:50.980
Well, the way we would do that is like this.

59
00:03:50.980 --> 00:03:52.860
Let's say we had a our user class

60
00:03:53.670 --> 00:03:56.610
and then the join table that we we're going to use--

61
00:03:56.610 --> 00:03:59.950
the joining class is called followings.

62
00:04:01.020 --> 00:04:03.780
So let's say we created a following class that had a user ID

63
00:04:03.780 --> 00:04:05.650
and a follower ID.

64
00:04:11.840 --> 00:04:16.940
Now, we could tell our user to say that it has_many followings.

65
00:04:18.399 --> 00:04:22.640
And then our following class would belong to a user.

66
00:04:23.490 --> 00:04:26.810
So this is just one part of the association.

67
00:04:27.430 --> 00:04:31.960
In order to do the other part where we're going to have a follower as well,

68
00:04:32.830 --> 00:04:35.480
we would say that it belongs to--

69
00:04:37.520 --> 00:04:39.070
we fix that right there--

70
00:04:39.560 --> 00:04:46.580
belongs to a follower, and the class name for that is user.

71
00:04:47.240 --> 00:04:49.940
In order to specify that it points back to a class

72
00:04:49.940 --> 00:04:52.600
other than what Rails usually infers,

73
00:04:53.090 --> 00:04:58.350
you use the class_name hash key when specifying it belongs to association.

74
00:04:58.840 --> 00:05:02.000
In this case, we're saying the class name is user.

75
00:05:02.440 --> 00:05:05.560
So it's just going to point back to a different user.

76
00:05:06.710 --> 00:05:12.960
Now, over on the user class, we say has_many followers,

77
00:05:14.300 --> 00:05:16.320
which is this part of the association here,

78
00:05:18.240 --> 00:05:21.810
through followings.

79
00:05:21.810 --> 00:05:24.450
And that's how you do a has_many association

80
00:05:24.450 --> 00:05:28.480
where the second part points back to the same kind of class.

81
00:05:29.680 --> 00:05:34.230
Behind the scenes, Rails will look up all of the follower IDs at the table

82
00:05:34.230 --> 00:05:36.690
and then do a separate query to the database

83
00:05:36.690 --> 00:05:38.740
to bring back those users.

84
00:05:39.050 --> 00:05:41.600
It's two database queries to get the information,

85
00:05:41.600 --> 00:05:44.210
but it's an extremely useful technique.
