This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/intermediate-rails-6
This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/intermediate-rails-6
In the video about single table inheritance, at 7:28, he misses the migration for creating following relationships. This is what the migration file looks like. Once you migrate that, you should be good to continue.
class CreateFollowingRelationships < ActiveRecord::Migration[5.1]
def change
create_table :following_relationships do |t|
t.belongs_to :follower
t.belongs_to :followed_user
t.timestamps
end
end
end
Sorry about the intendation. Not sure how to fix that in the comments
In the user model, why are we creating a
has_many :followers, through: :follower_relationships
as well as
has_many :follower_relationships, foreign_key: :followed_user_id, class_name: "FollowingRelationship", dependent: :destroy
?
Wouldn’t it make more sense to just do
has_many :followers, foreign_key: :followed_user_id, class_name: "FollowingRelationship", dependent: :destroy
?
Same applies to followed_users
and followed_user_relationships
.
My assumption is that we want to give the user a helper of user.followers and user.follower_relationships. But is that it? Isn’t there a better way?
I could be a little late to the party, but I want to know why the author is using: @_user
in FollowedUsersController
instead of plain @user
that I have been using so far.
What about the other constraints?
I wrote it like this:
create_table :following_relationships do |t|
t.integer :follower_id, foreign_key: true, null: false
t.integer :followed_user_id, foreign_key: true, null: false
end
add_index :users, [:follower_id, :followed_user_id], unique: true, name: 'some_name'
Do pass the option in add_index
for name
. Else, the index name will be too long for PostgreSQL.
If you do it like:
has_many :followers, foreign_key: :followed_user_id, class_name: "FollowingRelationship", dependent: :destroy
Well, if we do it like this:
user = User.first
user.followers
user.followers
will give us instances of FollowingRelaionship
class, and the table associated with class has the following two columns, among other columns:
follower_id | followed_user_id
So if you are asked to print all the usernames of all the users a particular user is following:
user = User.first
User.find(user.followed_user_relationships.map(&:followed_id))
Surely, you wouldn’t like doing: User.find(user.foll...
I use the code below:
rails generate Model FollowingRelationship follower_id:integer followed_user_id:integer
class CreateFollowingRelationships < ActiveRecord::Migration[5.1]
def change
create_table :following_relationships do |t|
t.integer :follower_id, foreign_key: true, null: false
t.integer :followed_user_id, foreign_key: true, null: false
t.timestamps
end
add_index :following_relationships, :follower_id
add_index :following_relationships, :followed_user_id
add_index :following_relationships, %i[follower_id followed_user_id], name: :relationship_index
end
end
why Matthew does not make a official reply?
I came up with this solution that ensures the foreign_keys align with the users table. If you skip ahead to 11:55 in the video you can see the migration that is being added to source control.
class CreateFollowingRelationships < ActiveRecord::Migration[5.0]
def change
create_table :following_relationships do |t|
t.integer :follower_id, null: false
t.integer :followed_user_id, null: false
t.timestamps
end
add_foreign_key :following_relationships, :users, column: :follower_id
add_foreign_key :following_relationships, :users, column: :followed_user_id
add_index :following_relationships, [:follower_id, :followed_user_id],
name: :index_follower_following_relationship,
unique: true
end
end
The add_index at the end is not required but an extra validation the database can perform.
Thanks @joshmosh for the pointer to the git diff at 11:55! (And sorry to revive this old thread again)
I wanted to use references
to keep it consistent with the previous migrations.
Eventually I got it to work and generate the same schema as @halogenandtoast (less some minor Rails 5.1 differences such as bigint instead of int for reference columns) using the following migration:
class CreateFollowingRelationships < ActiveRecord::Migration[5.1]
def change
create_table :following_relationships do |t|
t.references :follower, index: true, foreign_key: { to_table: :users }, null: false
t.references :followed_user, index: true, foreign_key: { to_table: :users }, null: false
t.timestamps
end
end
end
Hey! I believe he is using @_user
during assignment as a way to communicate to future collaborates/coders/etc that the method of assignment used in that line isn’t designed to be used for other things. In other words, the lines that all make conditional assignments with @_user
are specific to that intent… it shouldn’t be used as a generalized way to make assignments. One reason for this, for example, is if the assignments are made with conditions that wouldn’t give the same results if used elsewhere. I might be wrong on this, though.