Setting Up Foreign Keys in Rails with Postgres

I try to track mutual feelings when a user likes a user they like. To check if this is mutual, I call the method after it is created. If this symbol was similar, what is considered mutual.

However, the problem is that I encounter some odd errors that, it seems to me, are related to setting up foreign keys. I found that there are many associations in Rails, but when I try to access it, I get the error PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block : RELEASE SAVEPOINT active_record_1 .

User:

 class User < ApplicationRecord has_many :likes end 

how

 class Like < ApplicationRecord belongs_to :likee, class_name: 'User', foreign_key: 'likee_id' belongs_to :liker, class_name: 'User', foreign_key: 'liker_id' belongs_to :connection, optional: true after_save :mutual_like? private def mutual_like? if liker.likes.where(likee: liker) # fails end end end 

I tried changing the hook around saving, etc., but that also does not work.

Also, I can't even call Like.first else, I get the same error.

I tried to print liker.likes.where(likee: liker) and I get PG::UndefinedColumn: ERROR: column likes.user_id does not exist , which I think is the problem.

However, I can access self.likee like: self.likee inside the hook, but I cannot call self.likee.likes without returning #<Like::ActiveRecord_Associations_CollectionProxy:0x3fd91ca5ca78>

Scheme:

  create_table "likes", force: :cascade do |t| t.integer "liker_id", null: false t.integer "likee_id", null: false t.integer "connection_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["likee_id"], name: "index_likes_on_likee_id", using: :btree t.index ["liker_id"], name: "index_likes_on_liker_id", using: :btree end create_table "users", force: :cascade do |t| t.string "email" t.string "username" t.string "password_digest" t.boolean "admin", default: false t.index ["email"], name: "index_users_on_email", using: :btree t.index ["username"], name: "index_users_on_username", using: :btree end 

Tests:

 RSpec.describe Like, type: :model do let(:liker) { Fabricate(:user) } let(:likee) { Fabricate(:user) } let(:like) { Fabricate(:like, liker: liker, likee: likee) } let(:pending_like) { Fabricate.build(:like, liker: liker, likee: likee)} context 'relations' do it { should belong_to :likee } it { should belong_to :liker } describe 'liking another user' do it '#liker references first user' do expect(like.likee).to eq likee end it '#likee references second user' do expect(like.liker).to eq liker end end end ... RSpec.describe User, type: :model do context 'relations' do it { should have_many :likes } end ... 

Is this because I'm trying to find a saved record?

+5
source share
1 answer

liker.likes.where(likee: liker) returns only the relation. You should fulfill your request as follows: liker.likes.where(likee: liker).exists?

has_many :likes in your model User expects the user_id column in your likes table. Given the code, I would think you should change it to

 class User < ApplicationRecord has_many :other_likes, foreign_key: :liker_id has_many :likes, foreign_key: :likee_id end 

belongs_to :connection is a bad name in my point of view. ActiveRecord::Base has a class method with the same name. Perhaps someday you will run into problems with that association name.

+2
source

Source: https://habr.com/ru/post/1257883/


All Articles