Search code examples
ruby-on-railsrubysecurityassociationsbelongs-to

Securely building model associations


I'm trying to ensure my Rails app is securely building associations and I'm not sure how I should be handling the case where I have models that are essentially "owned" through another model.

An example would be that I'm a father who has teenage daughters. They own some apple products. The products are technically belong to them but I paid for it all -- I own it.

Furthermore, I don't want strangers just giving my daughters new apple products.

The code for this looks like:

class Father
  has_many :teenage_daughters

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

class TeenageDaughter
  belongs_to :father

  accepts_nested_attributes_for :apple_products, 
                                reject_if: :all_blank, 
                                allow_destroy: true # oh yeah
end

class AppleProduct
  belongs_to :teenage_daughter
  # Should i be doing something like this?
  # belongs_to :father 
end

My question is:

Should I be adding a belongs_to relation BACK to father inside of AppleProduct and somehow whenever i create AppleProducts I set current_user?

I am worried about making a mistake and somehow allowing a crafted request in that will allow people to associate/disassociate rows with user accounts that don't belong to them.


Solution

  • Let me quote something that you said:

    I paid for it all -- I own it

    What this means is that the AppleProduct model represents an asset that the father own, and you are letting somebody (in this case the kids) to use it. This is a, in my opinion, closer way to your real life model:

    class Father
       has_many :apple_products
       has_many :teenage_daughters
     end
    
     class TeenageDaughter
       belongs_to :father
     end
    
     class AppleProduct
       belongs_to :owner, class_name: 'Father'
       belongs_to :user, class_name: 'TeenageDaughter'
     end
    

    By doing this you have an explicit representation of who is the owner and the user of those products.

    Also, not relevant to your question, but consider changing the name from TeenageDaughter to Child.