0

I've been trying to implement a Facebook style friend system. I've read several tutorials and can't understand what I'm doing wrong. The friendship controller and the links in the views for adding friends work, but on the database level it throws an error.

When I open the rails console and put:

User.find(1).friends << User.find(2)

I get:

SQL (0.4ms)  INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 1], ["friend_id", 2], ["created_at", "2017-10-14 15:01:28.364691"], ["updated_at", "2017-10-14 15:01:28.364691"]]
(0.1ms)  rollback transaction
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: main.friends: INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)
from (irb):1

user.rb

has_many :friendships, dependent: :destroy
has_many :friends, through: :friendships

# these are used in the controller

def befriend(user)
  friends << user
end

def unfriend(user)
  friends.delete(user)
end

def friends?(user)
  friends.include?(user)
end

friendship.rb

belongs_to :user
belongs_to :friend, class_name: 'User', foreign_key: "friend_id"

validates :user_id, presence: true
validates :friend_id, presence: true

I'm using Devise for authentication.

mef27
  • 379
  • 4
  • 15

2 Answers2

0

You aren't creating friends (the other user already exists), but friendships.

user.rb

class User < ActiveRecord::Base
  has_many :friendships, dependent: :destroy
  has_many :friends, through: :friendships, source: :friend
end

friendship.rb

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, class_name: 'User'
end

console

User.find(1).friendship.create(friend_id: User.find(2).id)
rbb
  • 172
  • 1
  • 7
  • Hi, your code seems to produce the same error unfortunately. I think the issue is that when a Friendship is created, it throws the 'no such table: main.friends' error. The shovel syntax (<<) adds the second user into the first user's collection proxy and creates the friendship, but there seems to be a problem with creating friendships – mef27 Oct 14 '17 at 18:03
  • The `has_many :through` association means we can use the `append (<<)` method to create a Friendship. – felguerez Aug 06 '18 at 02:27
  • Removed source: :friend in class User, and it'll work – Nguyen Mar 07 '19 at 16:55
0

I created two tables named User and Friendship

> rails g model User first_name:string last_name:string
> rails g model Friendship user:references friend:references
> rake db:migrate

In user.db, defined two has_many associations:

class User < ApplicationRecord
    has_many :friendships, dependent: :destroy
    has_many :friends, through: :friendships
end

In friendship.rb:

class Friendship < ApplicationRecord
   belongs_to :user
   belongs_to :friend, class_name: 'User'
end

In rails console, I created two sample users and made them friends:

> User.create(first_name:"Blue", last_name:"Sky")
> User.create(first_name:"White", last_name:"Cloud")
> Friendship.create(user:User.first, friend:User.second)
> Friendship.create(user:User.second, friend:User.first)

Or:

> User.first.friendships.create(friend:User.second)
> User.second.friendships.create(friend:User.first)

Now you can retrieve all friends that belong to one user. For example:

> User.first.friends
Nguyen
  • 2,019
  • 1
  • 24
  • 31