Other Pages

Hooking Up Votes And Topics

Goals

    Topics
    id
    title
    description
    Votes
    id
    topic_id

    Because there is an explicit relationship between a topic and its votes, we need to specify that. In this step, we'll explicitly declare the relationship between votes and topics.

Steps

Step 1: Teach the Topic model about Votes

Edit app/models/topic.rb so that it looks like this:

class Topic < ApplicationRecord
  has_many :votes, dependent: :destroy
end

Step 2: Teach the Vote model about Topics

Edit app/models/vote.rb so that it looks like this:

class Vote < ApplicationRecord
  belongs_to :topic
end

Step 3: Play around with Topics and Votes in the Rails console

First, make sure you've made at least one topic on the site.

Next, open a Rails console in a terminal window:
rails c
Expected result:
$ rails c
Loading development environment (Rails 7.0.8)
2.3.0 :001 >

At the console, try the following things

See how many topics exist:
Topic.count
Save the first topic into a variable:
my_topic = Topic.first

my_topic here could have been any variable name, but we'll stick with my_topic for consistency.

Change the title of that topic to something else:
my_topic.update(title: 'Edited in the console')
Add a vote to that topic:
my_topic.votes.create
See how many votes that topic has:
my_topic.votes.count
Remove a vote from that topic:
my_topic.votes.first.destroy

Note that the things you can do to Model classes (like Topic and Vote), differ from the things you can do to Model instances (like my_topic, here). my_topic.votes is an association, and here behaves mostly like a model class.

Model class / association methods
  • Topic.first
  • Topic.last
  • Topic.all
  • Topic.count
  • Topic.find_by_id(5)
  • Topic.destroy_all
  • my_topic.votes.count
  • my_topic.votes.create
  • my_topic.votes.destroy_all
Model instance methods
  • my_topic.title
  • my_topic.title = 'New title'
  • my_topic.update(title: 'New title')
  • my_topic.save
  • my_topic.save!
  • my_topic.destroy
  • my_topic.votes.first.destroy

An exhaustive list of things you can do to models and associations can be found in the Active Record Query Interface RailsGuide.

Explanation

has_many and belongs_to:

  • In Rails, relationships between models are called associations.
  • Associations (usually) come in pairs.
  • A topic will have many votes so we put has_many :votes in the topic model.
    • When you ask a topic for its votes, you get an array of votes for that topic.
  • A vote is for a particular topic, so we put belongs_to :topic in the vote model.
    • When you ask a vote for its topic, you get the topic for that vote.

It can still be important to clean up after yourself! dependent: :destroy on has_many :votes means when a Topic gets destroyed, all the votes that correspond to it will be destroyed, too. Without dependent :destroy, those votes would live on the database forever.

Next Step: