4

我想做这样的事情:

puts Room.find(1,2,3) - Room.find(1,2)

以便它只Room.find(3)返回该 SQL 记录,而不是返回Room.find(1,2,3)给我的 3 条记录

4

4 回答 4

6

我认为这会更有效率:

first_id_list = [1, 2, 3]
second_id_list = [1, 2]
Room.find(first_id_list - second_id_list)

这样,您只需搜索您真正希望在查询中出现的 id,而不是获取不需要的行,然后实例化一堆 Room 对象,然后您会立即忽略这些对象,但 Ruby 仍然需要进行垃圾收集。

于 2013-04-16T19:03:27.827 回答
2

正如安东尼阿尔贝托在评论中指出的那样。这行得通。只有当你只找到一个房间实例时这不起作用。例如Room.find(1)将返回一个类的对象Room,而不是一个数组。因此,您将无法-在此 Speak 对象上使用二元运算符。为避免这种情况发生,请使用to_a方法。

Array.wrap(Room.find(1,2,3)) - Array.wrap(Room.find(1))
=> Room.find(2,3)
于 2013-04-16T18:27:26.740 回答
1

如果我省略puts...

1.9.3-p327 :029 > puts Link.find(1,2,3) - Room.find(1,2)
Room Load (0.5ms)  SELECT `links`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2, 3)
Link Load (0.4ms)  SELECT `links`.* FROM `rooms` WHERE `rooms` id` IN (1, 2)
#<Room:0x95bf6a4>
 => nil 

对比

1.9.3-p327 :026 > Link.find(1,2,3) - Link.find(1,2)
  Room Load (0.8ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2, 3)
  Room Load (0.4ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2)
 => [#<Room id: 3, url_address: "http://www.linux.org", alt_text: "Linux", group_id: 3, position: 347, created_at: "2010-10-26 14:41:05", updated_at: "2010-10-26 14:41:05", version_number: "", content_date: nil>] 
1.9.3-p327 :027 > puts Room.find(1,2)
  Room Load (0.3ms)  SELECT `rooms`.* FROM `rooms` WHERE `rooms`.`id` IN (1, 2)
#<Room:0x9724094>
#<Room:0x9723ea0>
 => nil 
于 2013-04-16T18:52:34.230 回答
0

您可以只使用 SQL 来执行此操作,这样您就不会浪费内存!

rooms = Room.where(id: [1,2,3])
            .where.not(id: [1,2])

或者

rooms = Room.where("id IN (?) AND id NOT IN (?)",[1,2,3], [1,2])
于 2018-02-22T18:13:19.860 回答