Search code examples
ruby-on-railsrubyactiverecord

Rails create/build with multiple foreign keys


i have 3 models on my Rails application:

class User < ApplicationRecord
  has_many :accounts
  has_many :expenses
end

class Account < ApplicationRecord
  belongs_to :user
  has_many :expenses

end
class Expense < ApplicationRecord
  belongs_to :user
  belongs_to :account
end

I want to be able to create an expense only using the account, as in this example:

account = current_user.accounts.first
account.expenses.create()
# now a new expense is created with the following data:
# account_id: account.id, user_id: account.user_id

Is this possible? I couldn't find anything similar or anything useful to solve this.

I just want to skip passing user_id when i create the expense and I'm wondering if it s possible.

Thank you.


Solution

  • While the creation scope won't inherit through multiple levels, you can achieve this using a simple before_validation hook that assigns1 from user:

    class Expense
      before_validation :assign_user_from_account
    
    protected
      def assign_user_from_account
        self.user ||= self.account&.user
      end
    end
    

    Where here that's possible because user can be implied from the Account record.


    1 Here I'm using "assign" instead of "set" as "set" is often misconstrued as a mutator method for those from languages that use the get_x/set_x pattern.