goterpsgo
goterpsgo

Reputation: 317

Inserting attribute to a join table

I want to insert a value into a join table attribute whenever I do an insert through my AR models. I'm using an HMT association with all the affected models.

It's arranged as follows... I have an accounts table model:

class TabAccount < ApplicationRecord
  has_many :tab_client_project_accounts
  has_many :tab_projects, through: :tab_client_project_accounts
end

That uses a join table model:

class TabClientProjectAccount < ApplicationRecord
  belongs_to :tab_account
  belongs_to :tab_project
end

To join to a project table model:

class TabProject < ApplicationRecord
  has_many :tab_client_project_accounts
  has_many :tab_accounts, through: :tab_client_project_accounts
end

In my controller I use the shovel operator to add accounts to projects:

@this_project.tab_accounts << _new_account unless @this_project.tab_accounts.include?(_new_account)

And it works as designed. But I also want to insert a value into my tab_client_project_accounts join table as part of that shovel operator. Is that possible? What's the normal best practice for doing this?

Upvotes: 1

Views: 325

Answers (3)

goterpsgo
goterpsgo

Reputation: 317

I just got it working as intended; this is what I have:

_account_type_list_member_id = RefAccountType.find_by_typename('List Member').id

@this_project.tab_client_project_accounts.build(
  :tab_account => _new_account,
  :ref_account_type_id => _account_type_list_member_id
).save unless @this_project.tab_accounts.include?(_new_account)

Upvotes: 0

Pablo
Pablo

Reputation: 3005

If you need more columns in the join table the << approach (without explicitly using the join table) will not work as it does not set any additional attribute. You can use the join model instead:

Your version (without the join table):

@this_project.tab_accounts << _new_account unless @this_project.tab_accounts.include?(_new_account)

Using the join table:

@this_project.tab_client_project_accounts.build(
  tab_account: _new_account, 
  additional_data: 'anything_you_need'
) unless @this_project.tab_accounts.include?(_new_account)

Upvotes: 2

praga2050
praga2050

Reputation: 773

Here is what you can do

tp = TabProject.find 1

tp.tab_client_project_accounts.build tab_account: TabAccount.find 1

or

tp.tab_client_project_accounts.build tab_account: TabAccount.create(name: 'Some Account Name')

tp.save!

This will ensure record in all the tables

Upvotes: 0

Related Questions