Reputation: 633
I am getting massively stuck on an belongs_to relationship that should be pretty simple in my mind.
If I create a database association in a migration from a Ticket to an Account, it makes a database field called 'account_id' on the Tickets table, which is fine. Then in my Ticket model I put:
belongs_to :created_by, class_name: 'Account'
But as of rails 5, belongs_to relationships automatically add a validation of presence of requirement for account_id. But if I pass in a created_by it fails the validation. As I want to validate presence of created_by not account_id. So I add the optional: true tag
belongs_to :created_by, class_name: 'Account', optional: true
then validate presence of created by separately
validates_presence_of :created_by
this all works, but I don't like that I contradict myself by saying optional and then validate it a line later for what is really the same field!
I then got to thinking what if the field in the database on the tickets table is actually called created_by and using some primary and foreign key stuff I build the relationship it should fix it right?
But I am unsure how to build the migration and then how on earth to write the belongs_to. I had tried:
add_column :tickets, :created_by, :bigint
add_index :tickets, :created_by
and
belongs_to :created_by, class_name: 'Account', foreign_key: :created_by, primary_key: :account_id
but this complete fails, however if I do
belongs_to :account, foreign_key: :created_by
this enables me to update created_by with say an account_id of 1, but if I run ticket.created_by
I get the int and ticket.account
returns the account. I want this to be the other way around.
Upvotes: 2
Views: 12988
Reputation: 633
So my issue was in the way the migration interacted with rails relationships. I was creating a column called created_by and storing an id in it. Which meant created_by returned the id not the relationship.
The migration should have looked like:
add_reference(:tickets, :created_by, foreign_key: {to_table: :accounts})
which creates a created_by_id on the tickets table. Then on the tickets model all I needed was:
belongs_to :created_by, class_name: 'Account'
and for an account to see its tickets you would be able to do:
has_many :tickets, foreign_key: 'created_by_id'
Upvotes: 9