The Whiz of Oz
The Whiz of Oz

Reputation: 7043

Rails - what would be the correct relations between models here?

I am a bit puzzled and looking for some advice

I have an app with Users, each User has a Company and each company has Transactions going on.

Company
has_many :transactions

Transaction
belongs_to :company

But now I am in the need of including Categories for better organization and management of the user transactions. I want the user to create Categories himself, and after that add new Transactions to the category he created directly. So kind of like Transaction now belongs_to a category. That being said I don't feel like breaking my current model, because it works as I want it too and just feels right (the company performs transactions).

My routes are already nested enough, so making another layer will uglify my situation even more. This

  resources :users do
    resources :companies, shallow: true do
      resources :transactions, shallow: true
    end
  end

Into

  resources :users do
    resources :companies, shallow: true do
      resources :categories, shallow: true do      
        resources :transactions, shallow: true
    end
  end
end

Any advice here? Maybe someone had similar dilemma? Should I establish multiple belongs_to on the Transaction model, or should I restructure? What would be the optimal routing in my situation? Thank you.

Upvotes: 0

Views: 48

Answers (3)

alexpls
alexpls

Reputation: 1964

Since I don't know the exact details of your implementation I can't give the best advise possible, but what I can do is tell you how I'd structure these relations based on my understanding of the relationships that you're trying to model:

Company
has_many :categories
has_many :transactions, through: :categories

Category
belongs_to :company
has_many :transactions

Transaction
belongs_to :category

You could route this in several ways. Also, if a user can only access the companies which they own then you don't need to include /user as part of the route, instead you can just get the user_id in your controller separately.

/[user]/[company]/[category]/[transaction]
/[user]/[company]/[transaction]

Please note that I haven't tested this, if you have issues with it let me know and I'll spin up a sandbox and make sure that it works.

Upvotes: 1

ScottM
ScottM

Reputation: 10452

You shouldn't confuse fleshing out your domain modelling – in this case, adding the Category model – from structuring your routes file. It's not compulsory to have controllers for every model in your domain.

In this case, it sounds like you want to adjust your model to something like:

def Company < ActiveRecord::Base
  has_many :categories
  has_many :transactions, through: :categories
end

def Category < ActiveRecord::Base
  belongs_to :company
  has_many :transactions
end

def Transaction < ActiveRecord::Base
  belongs_to :category
end

What you don't get 'out of the box' from the above model is a direct association from the transaction to the company – belongs_to doesn't have a :through option. However, calling .category.company on the transaction will get you to the correct model, and you can wrap that into an instance method within Transaction if needed.

You can, of course, retain your company_id attribute within your Transaction model and retain the belongs_to :company call. That gives you the upside of a direct link between each transaction and the company that made it. But it places an extra onus on you to maintain the relationships correctly. Ultimately, it's up to you which approach to take, depending on your business requirements.

When it comes to resources and routes, you shouldn't need to nest too deeply – especially as for any given transaction there will be only one category, and one company. Personally, I might opt for the following nesting (any shallow options omitted):

resources :companies do
  resources :categories
  resources :transactions
end

Ultimately again, concentrate on delivering straightforward forms to your users, and that'll tend to point towards straightforward approaches to routing.

Upvotes: 1

Thaha kp
Thaha kp

Reputation: 3709

Company
has_many :transactions

Category
has_many :transactions

Transaction
belongs_to :category
belongs_to :company

Add resources :categories out side.

Upvotes: 0

Related Questions