Ruby/Rails - 检查HABTM关系记录中是否存在子ID

6

我有一组被称为Tasks和Posts的资源,它们之间存在has_and_belongs_to_many (HABTM)关系。

它们的值还通过连接表相互关联。

create_table 'posts_tasks', :id => false do |t|
   t.column :post_id, :integer
   t.column :task_id, :integer
end

我的问题是如何检查特定任务的id是否存在于从@post.tasks创建的数组中?

irb(main):011:0> @post = Post.find(1)
=> #<Post id: 2, comment: "blah blah", created_at: "2011-10-18 03:40:30", updated_at:
irb(main):012:0> @post.tasks
=> [#<Task id: 1, description: "Test 1", created_at: "2011-10-18 03:
   22:05", updated_at: "2011-10-18 03:22:05">, #<Task id: 3, description: "Test 3",
   created_at: "2011-10-18 03:22:21", updated_at: "2011-10-18 03:22:21
    ">]

所以我的问题是,用Ruby写“@task = Task.find(2)”是否存在于@post.tasks中,如果存在则返回true或false的方式是什么?
4个回答

13
@post.tasks.where(:id => task_id).present?

与Gabelsman建议的相比,要轻得多。


1
这意味着如果您正在检查n个任务,则会进行n次查询。但仍然比被接受的答案要好。 - Amir Raminfar
1
不一定需要。您可以传递一个 task_ids 数组。 - Chirantan

10
@post.tasks.map(&:id).include?(task_id)

在这里,task_id是你想要检查的任务的id。简单来说,你将任务列表映射为它们id的数组,然后检查问题中的id是否在该数组中。如果你不熟悉map,建议你去了解一下,它非常棒。

ruby-docs


只是想指出这不一定是最好的答案。正确的方法取决于您已经加载了哪些数据以及您打算询问它的未来问题。数据库查询很昂贵!尽量减少它们。 - GabeIsman

3
假设您将has_and_belongs_to_many命名为:posts,那么在Rails中执行以下操作非常优化:@post.task_ids.include?(task.id)。我注意到这里提供的两个答案会导致n个选择语句。但使用task_ids可以缓存第一个查询,并且其余部分不需要从数据库进行SELECT语句。

2
你可以使用 exists? 方法来实现这个功能:

exists?

@post.tasks.exists?(id: task_id)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接