Search code examples
ruby-on-railsassociationsprimary-keyrails-activerecordmodel-associations

Rails association primary_key option


I understand that foreign keys are for specifying when you have a different column name (different than parent child's class name) on the child class. I know what primary keys and foreign keys are and have read the rails documentation on associations several times, but I can't figure out what the primary key option is for.

1) But what is the primary_key option for? How does it change the sql when an association is called?

2) In what instances would you need to specify the primary_key on association?

3) In what instances would you need to specify both the primary_key and foreign_key?

below is an example of specifying the foreign_key option on associations:

class User
has_many :texts, foreign_key: :owner_id

end

class Text
belongs_to :user, foreign_key: :owner_id

end


User Table
id| name |

Text Table
id| owner_id |name

Solution

  • Ok so I thought more about the SQL and figured it out. You use foreign_key option when your child has a different foreign_key name then your parent's classname_id BUT on your parent table, you are still using ID as your identifier.

    user table
    id|name|age
    
    text table
    id|random_id|conversations
    
    select * from user where user.id = text.random_id
    
    select * from text where text.random_id (foreign_key) = account.id (primary key)
    

    On the other hand, you use primary_key with foreign_key when you don't want to use id at all to link the relationship.

    user table
    id|userable_id|name|age
    
    text table
    id|userable_ss_id|conversations
    

    HERE: if you wanted to link the userable_ss_id to userable_id, you would include both primary_key and foreign_key options on both relationships.

    class User 
    has_many :texts, primary_key: :userable_ss_id, foreign_key: :userable_id
    end
    
    class Text 
    belongs_to :user, primary_key: :userable_ss_id, foreign_key: :userable_id
    end
    

    Basic rule of thumb:

    select * from text where text.(foreign_key) = account.(primary key)