4

I have the code below that works just fine for the deletion of record, but on attempting to insert records into the table, using the after_save callback, does nothing.

Essentially what I'm doing is creating a series of advanced relationships that should create or remove relationships from the table campaign_category_metro_bids. If I run in PHPMyAdmin there is no trouble. But clicking through and activating in rails only allows for the second callback, after_destroy to be called...

 class CampaignMetro < ActiveRecord::Base

    belongs_to :campaign
    belongs_to :metro

    after_destroy :destroy_category_campaign_metro_bid
    after_save    :create_category_campaign_metro_bid

    def create_category_campaign_metro_bid
        insert = "INSERT INTO campaign_category_metro_bids (campaign_id,category_id, metro_id, created_at, updated_at)
                    SELECT e.campaign_id, e.category_id, e.metro_id, NOW(), NOW()
                    FROM
                    (SELECT c.campaign_id, c.category_id, c.metro_id
                     FROM (SELECT a.campaign_id, a.category_id, b.metro_id
                           FROM campaign_categories a 
                           cross join campaign_metros b 
                           ON a.campaign_id = b.campaign_id) c) e
                    LEFT JOIN campaign_category_metro_bids d
                    ON d.campaign_id = e.campaign_id and
                       d.category_id = e.category_id and
                       d.metro_id    = e.metro_id
                    WHERE d.campaign_id is null and 
                          d.category_id is null and 
                          d.metro_id    is null;"

        ActiveRecord::Base.connection.execute(insert)
    end

    def destroy_category_campaign_metro_bid
        delete="DELETE d.*
                FROM campaign_category_metro_bids d
                LEFT JOIN
                (SELECT c.campaign_id, c.category_id, c.metro_id
                 FROM (SELECT a.campaign_id, a.category_id, b.metro_id
                       FROM campaign_categories a 
                       cross join campaign_metros b 
                       ON a.campaign_id = b.campaign_id) c) e
                ON d.campaign_id = e.campaign_id and
                   d.category_id = e.category_id and
                   d.metro_id    = e.metro_id
                WHERE e.campaign_id is null and 
                      e.category_id is null and 
                      e.metro_id    is null;"

        ActiveRecord::Base.connection.execute(delete)
    end
end

How can I get this to work?

Sauron
  • 6,399
  • 14
  • 71
  • 136

1 Answers1

4

The problem is that on after_save the transaction that will create the record on the database haven't been committed yet, so the record isn't really there yet. You have to use after_commit.

http://apidock.com/rails/ActiveRecord/Transactions/ClassMethods/after_commit

rafb3
  • 1,694
  • 12
  • 12
  • I tried that, it did not work. I am using the callbacks on a table that is being created through SQL calls, not active record – Sauron Dec 24 '14 at 00:00
  • Can you get any after save/commit callback at all to run in that model? If that's being created implicitly by adding metro to campaign or vice versa, then that would be the problem and we can explore solutions for that – rafb3 Dec 24 '14 at 00:29
  • I moved the entire process into a model that is being created with active record and it is running exactly as it should. No problems – Sauron Dec 24 '14 at 00:32
  • Are those models related with `has_and_belongs_to_many`? If so, then you can try using `has_many :through` http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association – rafb3 Dec 24 '14 at 00:38