Activerecord 删除记录不会破坏关联
我有一个任务模型和用户模型,我有一个连接表b/w任务和名为标记的用户。 Task.rb 但是这个测试失败了Activerecord 删除记录不会破坏关联,activerecord,ruby-on-rails-5,Activerecord,Ruby On Rails 5,我有一个任务模型和用户模型,我有一个连接表b/w任务和名为标记的用户。 Task.rb 但是这个测试失败了 Task untag should untag user from task Failure/Error: expect(@task2.tag_exists_for(@user)).to be false expected false got true 在进一步的调查中,我发现untagtag会删除标记记录,但当我调用task.tags时
Task untag should untag user from task
Failure/Error: expect(@task2.tag_exists_for(@user)).to be false
expected false
got true
在进一步的调查中,我发现untagtag会删除标记记录,但当我调用task.tags时,它会显示在collectionproxy中
Tag.find_by(id: 39)
Tag Load (0.3ms) SELECT `tags`.* FROM `tags` WHERE `tags`.`id` = 71 LIMIT 1
=> nil
2.4.1 :042 > t1.tags
=> #<ActiveRecord::Associations::CollectionProxy [#<Tag id: 39, user_id: "3", task_id: "37", created_at: "2018-01-18 11:13:23", updated_at: "2018-01-18 11:13:23">, #<Tag id: 43, user_id: "9", task_id: "37", created_at: "2018-01-22 04:56:13", updated_at: "2018-01-22 04:56:13">, #<Tag id: 44, user_id: "5", task_id: "37", created_at: "2018-01-22 05:31:16", updated_at: "2018-01-22 05:31:16">]>
2.4.1 :043 >
我来自Mongodb,nosql的背景,所以以前从未经历过这种行为。
有没有一种方法可以在不使用任何宝石的情况下删除关联,一些人建议使用偏执宝石,用真正的毁灭取代毁灭 之所以发生这种情况,是因为您销毁的标记对象仍然缓存在ruby中。这就是为什么重载解决了这个问题,因为它从数据库中重新获取标记 为了有一点性能提升,并且不必在测试中调用reload,我建议用以下方式重写标记了\u user\u id的方法:
def tagged_user_ids
tags.pluck(:user_id)
end
首先,这将调用一个SQL查询,只获取user_id列,而不是所有列。其次,对该方法的每次调用都将执行一个新的SQL查询,在这种情况下,如果删除一些标记,则该方法将反映结果,而无需在task对象上调用reload
另一个不相关的改进是将标记的任务改写为:
通过::tags完成了许多:标记的任务这可能很有趣:调用@task.reload解决了问题Hey@Kkulikovskis谢谢你的详细解释,但我似乎不知道这将如何工作通过::tags完成了许多:标记的任务,我必须在标记模型中进行更改吗also@Supertracer不,您不需要更改标签型号。可能需要指定source:attribute,因为标记的任务与标记关联的任务名称不匹配。
describe "untag" do
it "should untag user from task" do
create_task_and_tag_user
p @task2.tags
@task2.untag(@user)
p @task2.tags
expect(@task2.tag_exists_for(@user)).to be false
end
end
def create_task_and_tag_user
@user = User.create(email:"asd@jaka.com",password: 123456,name: "user1")
@task1 = @user.tasks.create(description: "some description")
@user2 = User.create(email:"user2@jaka.com",password: 123456,name: "user2")
@task2 = @user2.tasks.create(description: "some other task")
@task2.tag(@user)
end
Task untag should untag user from task
Failure/Error: expect(@task2.tag_exists_for(@user)).to be false
expected false
got true
Tag.find_by(id: 39)
Tag Load (0.3ms) SELECT `tags`.* FROM `tags` WHERE `tags`.`id` = 71 LIMIT 1
=> nil
2.4.1 :042 > t1.tags
=> #<ActiveRecord::Associations::CollectionProxy [#<Tag id: 39, user_id: "3", task_id: "37", created_at: "2018-01-18 11:13:23", updated_at: "2018-01-18 11:13:23">, #<Tag id: 43, user_id: "9", task_id: "37", created_at: "2018-01-22 04:56:13", updated_at: "2018-01-22 04:56:13">, #<Tag id: 44, user_id: "5", task_id: "37", created_at: "2018-01-22 05:31:16", updated_at: "2018-01-22 05:31:16">]>
2.4.1 :043 >
def tagged_user_ids
tags.pluck(:user_id)
end