In this project, we’re going to practice querying our tables more; in particular, we want to practice leveraging the foreign key columns we added to traverse associations between tables.
And, since we make these particular queries (the ones to find associated rows from other tables) so often, we’re going to add instance methods that wrap up the logic and make it a snap to use.
Here’s the what the domain model looks like in this application, using Entity Relationship Diagram notation:
It’s similar to the paper database we printed out on Day 1; if you have it, pull it out, because it will be very helpful to look at it while you are planning out how to write your queries.
I’ve already created these tables by running the following commands:
rails generate draft:model user username:string private:boolean likes_count:integer comments_count:integer
rails generate draft:model photo caption:text image:string owner_id:integer likes_count:integer comments_count:integer
rails generate draft:model follow_request sender_id:integer recipient_id:integer status:string
rails generate draft:model like fan_id:integer photo_id:integer
rails generate draft:model comment photo_id:integer body:text author_id:integer
I’ve already run
rails db:migrate to execute these instructions, and also
rails dev:prime to pre-populate them with some dummy data.
Pop open a
rails console and verify that the models got set up correctly:
User.count Photo.count FollowRequest.count Like.count Comment.count
In your live app, you can visit the URL
http://[YOUR DOMAIN]/admin (or click “▶️ ActiveAdmin” in the menu) and check out the data being created via our quick-and-dirty dashboard (provided by the ActiveAdmin gem).
If for some reason later you want to reset the database to square one, you need to first destroy it:
and then re-create all of the tables:
and then re-populate them:
However, that last step might take a while.
Your goal, ultimately, will be to define instance methods that perform frequently-used queries. While you’re trying to figure out how to do so, it will probably be helpful to bounce between the
rails console (to experiment) and your model files (to define instance methods, which could potentially require many lines to ultimately
return the correct thing). Remember that if you make any changes to a model file, you must
reload! in the
rails console and recreate any variables you were using before the new logic will be available.
Here are some
rails console appetizer queries to try. For the user
.distinctthat you can call on a collection to remove duplicates.
Ultimately, define the following instance methods to encapsulate the logic you discovered in the appetizer queries:
Note: In the Ruby community, a shorthand for saying “an instance method1 called
Photo” is “
Photo#zebra”. (Unfortunately this is yet another thing that the octothorpe symbol is (over)used for.)
Photo#postershould return the user who posted the photo.
Photo#commentsshould return the comments made on the photo.
Comment#commentershould return the user who authored the comment.
Photo#likesshould return the likes made on the photo.
Photo#fansshould return the users that have liked the photo.
Photo#fan_list should return the usernames of the users that have liked the photo as a sentence.
Hint: Rails adds a handy method to
Arrays of strings called
User#commentsshould return the comments the user has made.
User#own_photosshould return the photos posted by the user.
User#likesshould return the likes created by the user.
User#liked_photosshould return the photos the user has liked.
User#commented_photosshould return the photos the user has commented on.
User#sent_follow_requestsshould return all of the follow requests that were sent by the user.
User#received_follow_requestsshould return all of the follow requests that were received by the user.
User#accepted_sent_follow_requestsshould return the follow requests that were sent by the user and accepted.
User#accepted_received_follow_requestsshould return the follow requests that were received by the user and accepted.
User#followersshould return the people whose follow requests the user has accepted.
User#followingshould return the people that have accepted the user’s follow requests.
User#feedshould return the photos posted by the people the user is following.
User#discovershould return the photos that are liked by the people the user is following.
rails grade when you’re ready to see how you’re doing.
The analogous shorthand for class methods uses a
. instead of the
#: “a class method on
zebra” is abbreviated “