Bummer! This is just a preview. You need to be signed in with a Pro account to view the entire video.
How to Create Associations in Rails8:04 with Jim Hoskins
[?music?] 0:00 [Master Class: Designer and Developer Workflow: Associating Jobs and Users] 0:02 [Jim Hoskins] So let's take a look at the application we have so far 0:05 and see what the next steps are for us. 0:08 Right now, we have the ability to list jobs and view specific jobs 0:10 and we can go back and we have the ability to register as well as sign in. 0:16 When we go ahead and try this out-- 0:24 let's see if I can remember my password-- 0:26 and we have the ability to sign in here, so we have an authentication system 0:29 and the ability in our application to see if somebody is signed in or signed out. 0:33 And of course, we can just go ahead and sign out again. 0:38 So the authentication system is a great first step, 0:41 but it's really a means to an end and that end is to make sure 0:44 that people can manage the job that they create 0:49 as well as only people who are registered users and logged in can create accounts 0:52 and to make sure that nobody can edit somebody else's job. 0:57 So we have an authentication system in place, but now we need to worry about authorization 1:01 and making sure that the right people can do the right tasks on our site. 1:05 So since one of the main goals is to make sure that somebody can only edit 1:10 the jobs that they created, we need to have some way of associating a user 1:14 with the job that they've created. 1:19 That way, when somebody tries to edit it, 1:21 we can compare the person who's trying to do the edit with the person who created the job. 1:23 So what we're going to want to do is associate a user with a job, 1:28 so Rails offers association helpers, which make this pretty easy to do. 1:32 Basically, all we need to do is add a field to the job 1:36 which will hold the ID of the user who created it 1:40 and by using conventions and built-in association methods, 1:43 we can have a lot of easy ways to ensure that a job is always associated with a user. 1:47 So the first step for this is to add the actual field, and for that, 1:53 we'll go ahead and create a migration in Rails. 1:56 A database migration is simply our way of describing to Rails 1:59 how our database is changing over the development cycle, 2:04 so since we want to add a field to a table, 2:07 we want to specify that as we move forward, we want to add this column to the table, 2:11 and if we wanted to go back a version, it would also explain how to go back 2:16 to a previous version of the database. 2:19 We'll go ahead generate a new migration, and to do that, 2:22 we'll do $rails generate migration 2:25 and I'm going to give this migration a name 2:30 and we want to add a user_id column to the jobs table, 2:32 and the user id column is where we'll store the user_id 2:37 of the person who is associated with that job--the owner of that job. 2:41 So there's actually a special naming convention we can use that will actually generate 2:46 pretty much most of our migration for us, 2:50 so I'm going to call this add_user_id_to_jobs 2:52 and it's really the add to jobs part that is triggering the special behavior. 3:01 Rails now knows that we are adding a field to a job 3:06 so we can actually specify that field after it by typing in user_id:integer. 3:10 So now, hopefully, instead of creating an empty migration, 3:19 we should get a migration that already has what we need to add this one field to the table. 3:22 Now, hopefully, instead of creating an empty migration, we'll create a migration 3:27 that has the code we need to add this column to the table. 3:31 So now we have a new file in db/migrate that's called _add_user_id_to_jobs 3:38 so let's go ahead and take a look at it. 3:42 Just open up db/migrate, 3:46 grab this last one. 3:49 We can see that the generator actually understood what we wanted. 3:52 We're adding a column to the jobs table called user_id 3:54 and it's of types integer, and if we wanted to roll back this change, all we need to do 3:58 is remove the column user_id from jobs. 4:02 So let's go ahead and actually migrate our database. 4:06 If we want to take a look at what the schema looks like right now, 4:09 we can see that the jobs table has title, description, company_name, 4:12 created_at and updated_at. 4:17 When we go ahead and run this migration by typing in $rake.db:migrate, 4:19 we'll see it has added the column, 4:27 and if we go back to our schema.rb here, we can see that the table jobs now has an integer 4:29 user_id column. 4:34 So now we have a user_id column in our jobs field, so what we want to do now 4:37 is create the associations between jobs and users so we can use it programmatically 4:41 in our controllers and views. 4:46 So the first thing we'll do is open up app/models/job, 4:49 and so if the job table contains a user_id field, the relationship between job and users 4:55 is that job belongs to a user and that's because the user_id is marked on the job's actual table. 5:01 So in order to do this, we will write belongs_to 5:10 and all we need to do is say :user 5:16 and what this does is creates a user method on the job 5:20 which we can use to actually assign or retrieve instances of the user class 5:24 which will be based on the user_id column in our database. 5:28 Since we called that column user_id 5:34 and the class that we're associating with is called user, 5:37 we don't have to specify anything more than this because Rails will infer all of those things 5:41 based on its defaults, so we'll save this. 5:46 So now we've associated user to job, 5:50 but let's go ahead and do the inverse, associate jobs to user. 5:52 So we'll open up user.rb and I'll write has_many: jobs. 5:57 And by default, Rails will assume that there is a job model 6:06 and that job model has a user_id column in it 6:09 that associates to this class's primary key, which it does. 6:12 So since we're going with the Rails assumptions, we have to write very little code 6:16 to associate it. 6:21 So now if we have a user instance, we can call jobs, which would return an array of all the jobs 6:23 that are associated with that user, and that will come in handy later. 6:27 So let's go into the console and see how this works. 6:32 I'll go ahead and type $rails c or $rails console 6:37 and let's grab the first user by just typing in User.first 6:42 and I'll assign it to the lowercase user variable. 6:47 So here we have the user jim@carsonified, the one that I have been using, 6:51 and let's grab the first job and assign it to a job here 6:55 and we'll just grab Job.first. 7:00 So now we have Ice Cream Tester and my user account in variables here, 7:05 both user and job. 7:11 So if I wanted to say job.user = user, our local user variable here, 7:13 we can assign it just like that and what Rails does under the covers 7:22 is assign this job's user_id to the user instances idea 7:27 and all we need to do is job.save. 7:31 And if we wanted to say job.user_id, for instance, we'll see it's 1. 7:34 So now, any time that we grab this job, we can simply type in job.user 7:40 and Rails will go into the database and instantiate the user based on the user_id. 7:44 And this is pretty handy because it's easier to work with the actual model instances 7:51 than worry about foreign keys and primary keys and all of that. 7:55 So this will be pretty good, and let's see how we can integrate this into our application. 8:00
You need to sign up for Treehouse in order to download course files.Sign up