Home Rails - destroy associations from object with condition
Reply: 3

Rails - destroy associations from object with condition

larz
1#
larz Published in 2018-01-13 00:12:39Z

I have an object @foo with a :has_many associations to bar and I want before foo is destroyed all association objects from bar will be destroyed too if the bar has the property type = test.

the following code is working and the foo object is deleted but the bars are still there: (if I dont't use the condition .where(type: "test) all bars will be deleted)

  def destroy
    @foo.bars.each{|b| b.update_attribute(:blub_id, nil)}
    @foo.bars.where(type: "test").destroy_all
    @foo.destroy
    respond_to do |format|
      format.html { redirect_to foo_url, notice: 'Foo was successfully destroyed.' }
      format.json { head :no_content }
    end
  end
Mahmoud Sayed
2#
Mahmoud Sayed Reply to 2018-01-13 00:34:37Z

Just remove @foo.bars.each{|b| b.update_attribute(:blub_id, nil)} and make another try. I supposed that blub_id is a foreign key that indicates to which foo the current bar belongs to.

When you make the blub_id is equal to null, the records with a blub_id null is belongs to nothing and then @foo.bars.where(type: "test").destroy_all doesn't include these bars.

Ronan Lopes
3#
Ronan Lopes Reply to 2018-01-13 00:40:25Z

Don't know if that's a overall rule or just for that controller action, but I think would be better to do that on the model.

Don't know what exactly what the line

@foo.bars.each{|b| b.update_attribute(:blub_id, nil)}

does, but if blub_id is the foreign key, you should do that AFTER destroying the bars with test type. On your foo model, you can do it like this:

before_destroy :destroy_test_bars

def destroy_test_bars
   self.bars.where(type: "test").destroy_all
   self.bars.update_all(blub_id: nil)
end

Then, on your controller, it would be just

  def destroy
    @foo.destroy
    respond_to do |format|
      format.html { redirect_to foo_url, notice: 'Foo was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

Think it could work. Good luck!

Ritesh Ranjan
4#
Ritesh Ranjan Reply to 2018-01-13 02:39:09Z

One of the good way will be to add after_destroy callback where you can write any logic you want.

class Foo < ActiveRecord::Base
  has_many :bars
  after_destroy :cleanup

  private
  def cleanup
    if self.bars.where(type: "test")
      self.bars.destroy_all
    end
  end
end 
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.303107 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO