插入违反外键约束

时间:2019-05-17 20:16:05

标签: ruby postgresql

我的模特:

class Team < ApplicationRecord
    belongs_to :objective
    belongs_to :consultancy
    has_one :seminar, :through => :consultancy

    belongs_to  :consultant, class_name: "Student"

    has_and_belongs_to_many  :users
end

class User < ApplicationRecord
    has_and_belongs_to_many  :teams
end

我的功能:

def find_placement(student)
    team = @consultancy.teams.detect{|x| x.has_room && student.objective_students.find_by(:objective => x.objective).obj_ready_and_willing?}
    team.users << student if team && team.valid? && team.persisted?
    return team
end

这是我当前收到的错误:

PG::ForeignKeyViolation: ERROR: insert or update on table "teams_users" violates foreign key constraint "fk_rails_8299e376e9" DETAIL: Key (team_id)=(3396) is not present in table "teams". : INSERT INTO "teams_users" ("user_id", "team_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4)

此错误仅在生产环境中发生,而不在开发或测试中发生。  我尝试使用控制台模式来手动运行函数的每一行。没有错误被触发。

从这个问题https://dba.stackexchange.com/questions/29147/postgresql-insert-update-violates-foreign-key-constraints,我找到了这个解释。

“如果插入了新行,请检查DataID和Address:如果它们包含非NULL值(例如27856),请检查Table1的DataID˙和Table2的Address。如果其中没有这样的值这些表,然后返回错误。”

如果我正确理解本段内容,则是我的职能是尝试将一个学生加入到一个不存在的团队中。但是不是“如果team && team.valid?&& team.persisted吗?”我的代码的一部分能解决这个问题吗?如果没有,那么将学生加入团队的更好方法是,但前提是该团队已经存在。

在此先感谢您提供任何见解。

2 个答案:

答案 0 :(得分:1)

valid?方法不检查数据库持久性,因此您可能需要也可能不需要。您可能需要确保team模型得以保留,并且不会从teams表中删除。为了安全起见,您可以同时检查两者。 ActiveRecord#persisted?方法:

def find_placement(student)
  if team = @consultancy.teams.detect{|x| x.has_room && student.objective_students.find_by(:objective => x.objective).obj_ready_and_willing?}
    team.users << student if team.valid? && team.persisted?
  end
  team
end

答案 1 :(得分:1)

克服这个问题的关键是重新加载。

之前,@ consultancy正在收集所有团队,包括一些已被摧毁的团队。

@consultancy.reload.teams

仅收集仍然存在的团队。

没有@SergioTulentsev的评论和@lacostenycoder的答复,我将不会得出这个结论。谢谢!