Я пытаюсь создать обратную связь, когда пользователь принимает запрос на добавление в друзья, чтобы оба пользователя увидели друг друга в списке как «друг». Я делаю это с помощью метода create_inverse_relationship
, однако, кажется, что запускает бесконечный цикл:
Started PATCH "/friend_requests/4" for 127.0.0.1 at 2018-05-17 07:25:59 -0400
Processing by FriendRequestsController#update as HTML
Parameters: {"authenticity_token"=>"pvzhfmGkVrAyXYQRWaSx9DDovRo20SbkeEV9eD6B9aaQADVYfuSNmzZ4z1W4Kr8lxl+Y17w7ozEG9g1O+9eBDw==", "id"=>"4"}
FriendRequest Load (0.4ms) SELECT "friend_requests".* FROM "friend_requests" WHERE "friend_requests"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
(0.1ms) begin transaction
SQL (2.3ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["friend_id", 3], ["created_at", "2018-05-17 11:25:59.126334"], ["updated_at", "2018-05-17 11:25:59.126334"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 3], ["friend_id", 1], ["created_at", "2018-05-17 11:25:59.131665"], ["updated_at", "2018-05-17 11:25:59.131665"]]
SQL (0.1ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["friend_id", 3], ["created_at", "2018-05-17 11:25:59.133409"], ["updated_at", "2018-05-17 11:25:59.133409"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 3], ["friend_id", 1], ["created_at", "2018-05-17 11:25:59.135164"], ["updated_at", "2018-05-17 11:25:59.135164"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["friend_id", 3], ["created_at", "2018-05-17 11:25:59.137183"], ["updated_at", "2018-05-17 11:25:59.137183"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 3], ["friend_id", 1], ["created_at", "2018-05-17 11:25:59.139993"], ["updated_at", "2018-05-17 11:25:59.139993"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["friend_id", 3], ["created_at", "2018-05-17 11:25:59.143135"], ["updated_at", "2018-05-17 11:25:59.143135"]]
SQL (0.4ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 3], ["friend_id", 1], ["created_at", "2018-05-17 11:25:59.145367"], ["updated_at", "2018-05-17 11:25:59.145367"]]
SQL (0.2ms) INSERT INTO "friendships" ("user_id", "friend_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 1], ["friend_id", 3], ["created_at", "2018-05-17 11:25:59.148439"], ["updated_at", "2018-05-17 11:25:59.148439"]]
Это продолжается некоторое время, и в конце концов он говорит:
SystemStackError (stack level too deep):
app/models/friendship.rb:11:in `create_inverse_relationship'
И я должен убить сервер.
Из того, что я могу сказать, проблема в обратном вызове after_create :create_inverse_relationship
, но я не совсем уверен, что это за исправление.
Модель моей дружбы выглядит так:
class Friendship < ApplicationRecord
after_create :create_inverse_relationship
after_destroy :destroy_inverse_relationship
belongs_to :user
belongs_to :friend, class_name: 'User'
private
def create_inverse_relationship
friend.friendships.create(friend: user)
end
def destroy_inverse_relationship
friendship = friend.friendships.find_by(friend: user)
friendship.destroy if friendship
end
end
Это модель friend_request:
class FriendRequest < ApplicationRecord
belongs_to :user
belongs_to :friend, class_name: 'User'
validate :not_self
validates :user, presence: true
validates :friend, presence: true, uniqueness: {scope: :user}
def accept
user.friends << friend
destroy
end
def not_self
errors.add(:friend, "You can't add yourself!") if user == friend
end
end
И действие контроллера friend_request для уничтожения запроса после создания дружбы:
def destroy
@friend_request.destroy
head :no_content
end