views:

19

answers:

1

I need help on what I think should be an ActiveRecord Callback.

What I am trying to achieve is, each time a particular record is saved, ActiveRecord actually saves 2 records in the same table.

I will stay away from why I want this, it should be good enough to know that each transaction needs 2 separate but similar records saved in the same table.

Example:

0) I have a table called "links" which will store people linked to other people. It looks like this:

+----+-----------+---------------+-------------+
| id | person_id | origin_person | rcvd_person |
+----+-----------+---------------+-------------+

1) The web app user will enter in the originating person and the receiving person (who is originating or receiving the link). At this point the "person_id" is blank:

+----+-----------+---------------+-------------+
| id | person_id | origin_person | rcvd_person |
+----+-----------+---------------+-------------+
| 1  |           | 5             | 10          |
+----+-----------+---------------+-------------+

2) Before the record saves, I need the value of the "origin_person" copied over to the "person_id column:

+----+-----------+---------------+-------------+
| id | person_id | origin_person | rcvd_person |
+----+-----------+---------------+-------------+
| 1  | 5         | 5             | 10          |
+----+-----------+---------------+-------------+

3) Finally, once the record has been saved, I need a duplicate record saved, but with the "rcvd_person" value copied over to the "person_id":

+----+-----------+---------------+-------------+
| id | person_id | origin_person | rcvd_person |
+----+-----------+---------------+-------------+
| 1  | 5         | 5             | 10          |
+----+-----------+---------------+-------------+
| 2  | 10        | 5             | 10          |
+----+-----------+---------------+-------------+

This is exactly what I am trying to do, so if you can help me with an idea of how this could be achieved that would be appreciated.

I would rather keep all of this out of the Rails View, as I don't want hidden fields and what not hanging around.

One problem I ran into in trying to solve this, was that it would loop. I wrote some code (that didn't work) that would create a new record once a record was saved, but each save would trigger a new record which was a new save which ....

+1  A: 

You can add a flag to your model which could be used to prevent row duplication. That way when you create a new entry it gets saved after_* callback is called and in it you create a new object and set the duplication flag to prevent further duplication.

Something along the lines of:

def Link
  after_create :duplicate_link
  attr_accessible :stop_duplication

  private
  def duplicate_link
    unless stop_duplication
      new_link = Link.new
      # set all the link attrs here
      new_link.stop_duplication = true
      new_link.save
    end
  end
end

(of course this code is not tested, I just wanted to illustrate how it can be done)

That being said, I would really think hard why and if I need this type of behavior. It seems to me that something else might be wrong if you need this.

Slobodan Kovacevic
Thanks Slobodan. The reason I wanted this behavior is that in order to get the records I wanted I would need to use custom sql find, which meant I would break a lot of things I already had like paginate and so forth. I will probably have to bite the bullet and make my Rails work with a proper design. But thank you for clearing up how this could be done.
Dale