0
votes

Maybe I'm just drowning in a glass of water...

I have two models.

class Queue
has_many :slots
end

class Slot
end

Execute this command in rails c

q = Queue.create
s1 = Slot.create
s2 = Slot.create
s3 = Slot.create
q.slots << [ s1, s2, s3, s2, s3 ]

Now I want to delete ONLY the second element from q.slots list, without deleting others s2 elements (as #delete do). Something like q.delete_at(1). Any suggestions?

Thanks.

EDIT:

this is my schema.rb

create_table "steps", force: true do |t|
t.integer value
end

create_table "queues", force: true do |t|
t.string name
end

create_table "steps_queues", force: true do |t|
t.integer "step_id"
t.integer "queue_id"
end

add_index "steps_queues", ["step_id"], name: "index_steps_queues_on_step_id"
add_index "steps_queues", ["queue_id"], name: "index_steps_queues_on_queue_id"

EDIT II:

I resolved this problem adopting the has_many {:through} association. Not very good idea adding an object model to achieve a non business logic purpose. But, hey, it'works.

3
Well for starters you have to save what you create in the console. So q.save s1.save ect...Joel
Ok wrong example :D I tested with already created objects in my rails console session. But the problem still remains.MinasMazar

3 Answers

0
votes
a = [1,2,3,4,5,6]

a.delete_at(2) # a = [1,2,4,5,6]

The delete_at method will delete the index of the array you pass it.

If you want to remove an item based on its value you can use the delete method.

pets = ['cat', 'dog', 'rabbit', 'parrot']

a.delete('dog')

# pets = ['cat', 'rabbit', 'parrot']

Hope this helps

0
votes

ActiveRecord::Associations does not respond to #delete_at (it responds but nothing happens), but Array do it! So:

arr = q.steps.to_a # return an Array
arr.delete_at(index_of_item_to_remove)
q.steps = [ ] # Eliminates all associations. This is a transaction with q.steps.size updates.
q.steps = arr # Insert associations of arr. This is a transaction with arr.steps.size updates.

Array#delete_at remove only the target item, while ActiveRecord::Associations#delete remove all equivalent items.

This approach is not the best, cause cost (2 * (q.steps.size - 1) number of updates. Could be implemented a custom SQL statement, this break astraction and it's a bad practice...sounds dirty. :@

Still looking for a better solution

0
votes

This will work:

q.slots[1].destroy # will destroy the second record, it will remain in the association cache though
q.slots(true)      # if you need the association again, passing true will refetch

You could also try:

q.slots.delete q.slots[1].destroy

This should remove the element from the cached association, without need for reload.