ActiveRecord: update a foreign key in an association table

Hello,

I'd like to know how to update a foreign key in an association table (many_to_many association) ?

Here is my model, Split is the association table between Account and Transaction:

class Account < ActiveRecord::Base     set_primary_key :guid

    has_many :splits, :foreign_key => 'account_guid', :primary_key => 'guid'     has_many :transactions, :through => :splits end

class Transaction < ActiveRecord::Base     set_primary_key :guid

    has_many :splits, :foreign_key => 'tx_guid', :primary_key => 'guid'     has_many :accounts, :through => :splits end

class Split < ActiveRecord::Base     belongs_to :transaction, :foreign_key => 'tx_guid', :primary_key => 'guid'     # here is the association that I'd like to change:     belongs_to :account, :foreign_key => 'account_guid', :primary_key => 'guid' end

I'm trying this but it does not work (the value is not updated):

account = Account.new transaction.splits.first.account = account # error: prints the old value of account puts transaction.splits.first.account

Do you have any idea ? Do I need to create a new Split and delete the old one or is it possible to update the existing one ?

Thank you for your help,

Fabrice

Did you save the split after updating it? transaction.splits.first.account will go back to the database. Try something like split = transaction.splits.first split.account = account split.save!

You might need to reload transaction to get it to notice the change.

Is this GnuCash by any chance? I have written a read-only rails interface for GnuCash for report generation.

Colin

I'm trying this but it does not work (the value is not updated):

account = Account.new transaction.splits.first.account = account # error: prints the old value of account puts transaction.splits.first.account

Do you have any idea ? Do I need to create a new Split and delete the old one or is it possible to update the existing one ?

If the collection (in this case transaction.splits) isn't loaded then foo.first (and foo.last) will fetch just that one row from the database. The way it's implemented, foo.first returns a fresh object each time, so transaction.splits.first.account = account does assign account to that split, however

when you call transaction.splits.first.account it's fetching a fresh copy of that split.

if you did foo = transaction.splits.first; foo.account = account then you'd be able to see that the assignment did actually happen

Fred

Thank you for your advice,

Colin, yes, it's a GnuCash application which assigns an account to transactions

based on keywords

I solved my problem by defining a primary key on the association table 'Splits':

class Split < ActiveRecord::Base   set_primary_key :guid   ... end

Sincerely,

Fabrice