【发布时间】:2018-03-21 18:48:22
【问题描述】:
我有3个模型如下:
class Document < ActiveRecord::Base
has_many :documents_tasks, inverse_of: :document
has_many :tasks, through: :documents_tasks, dependent: :destroy
end
class Task < ActiveRecord::Base
has_many :documents_tasks, inverse_of: :task
has_many :documents, through: :documents_tasks, dependent: :destroy
end
class DocumentsTask < ActiveRecord::Base
belongs_to :task, inverse_of: :documents_tasks
belongs_to :document, inverse_of: :documents_tasks
validates_uniqueness_of :document_id, scope: :task_id
end
在上面,当我尝试更新 Task 的记录时,如果我保留验证,则会对 DocumentsTask 模型上的重复条目引发验证错误,或者如果删除验证则直接插入重复项。
我更新任务记录的代码是:
def update
@task = @coach.tasks.find(params[:id])
@task.update(:name => task_params[:name], :description => task_params[:description] )
@task.documents << Document.find(task_params[:documents])
if @task.save
render 'show'
else
render status: 500, json: {
error: true,
reason: @task.errors.full_messages.to_sentence
}
end
end
我知道我可以将unique index 添加到数据库以自动防止重复条目,但是有什么方法可以防止controller 在它们相同时更新连接表值?
所以当我尝试更新相关文档时,例如:
- 我最初有文档 5
- 现在我添加文档 6 并调用更新函数
它尝试将文档 5 和 6 重新添加到数据库中,所以我得到了错误:
Completed 422 Unprocessable Entity in 9176ms
ActiveRecord::RecordInvalid (Validation failed: Document has already been taken)
这是因为我添加了以下验证:
validates_uniqueness_of :document_id, scope: :task_id
在我的 DocumentsTask 模型中,如上所示。问题是如何防止它尝试重新添加现有记录
【问题讨论】:
-
您能否发布您遇到的具体错误或更新请求的日志?乍一看,如果您只是将
@task.update替换为@task.assign_attributes,您可能会很好,因为您现在正在调用更新,然后立即保存(这将保存数据两次,因此有可能重复)。但是如果不看更多细节就不能肯定地说。 -
@Matt 它会抛出一般的
model validation错误,因为它试图在连接表中重新插入现有值。问题是由于它尝试将现有值插入到连接表中,因为它们作为参数的一部分传递给它 -
不完全关注(对不起:S)。您可以发布更新请求的日志吗?
-
@Matt 我编辑了我的问题以添加更多信息
-
谢谢,我做了几个假设并发布了答案。希望对您有所帮助!
标签: ruby-on-rails ruby-on-rails-4 join activerecord