为了讨论的目的,我用两张表做了一个测试:
:stones and :bowls (both created with just timestamps - trivial)
create_table :bowls_stones, :id => false do |t|
t.integer :bowl_id, :null => false
t.integer :stone_id, :null => false
end
这些模型是不言自明的,基本的,但在这里它们是:
class Stone < ActiveRecord::Base
has_and_belongs_to_many :bowls
end
class Bowl < ActiveRecord::Base
has_and_belongs_to_many :stones
end
现在,问题是:我希望每个碗里有许多相同的石头。我希望能够只移除一个,而将其他相同的石头留在后面。这看起来很基本,我真的希望我既能找到解决方案,又不会觉得自己太白痴。
这是一个测试运行:
@stone = Stone.new
@stone.save
@bowl = Bowl.new
@bowl.save
#test1 - .delete
5.times do
@bowl.stones << @stone
end
@bowl.stones.count
=> 5
@bowl.stones.delete(@stone)
@bowl.stones.count
=> 0
#removed them all!
#test2 - .delete_at
5.times do
@bowl.stones << @stone
end
@bowl.stones.count
=> 5
index = @bowl.stones.index(@stone)
@bowl.stones.delete_at(index)
@bowl.stones.count
=> 5
#not surprising, I guess... delete_at isn't part of habtm. Fails silently, though.
@bowl.stones.clear
#this is ridiculous, but... let's wipe it all out
5.times do
@bowl.stones << @stone
end
@bowl.stones.count
=> 5
ids = @bowl.stone_ids
index = ids.index(@stone.id)
ids.delete_at(index)
@bowl.stones.clear
ids.each do |id|
@bowl.stones << Stone.find(id)
end
@bowl.stones.count
=> 4
#Is this really the only way?
所以……真的是把整个东西吹走并用钥匙重建它真的是唯一的方法吗?