after_create приводит к бесконечному циклу INSERT INTO SQL - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь создать обратную связь, когда пользователь принимает запрос на добавление в друзья, чтобы оба пользователя увидели друг друга в списке как «друг». Я делаю это с помощью метода 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

1 Ответ

0 голосов
/ 17 мая 2018

Попробуйте поставить условное в 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) unless already_friended?
  end

  def destroy_inverse_relationship
    friendship = friend.friendships.find_by(friend: user)
    friendship.destroy if friendship
  end

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

end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...