Reputation: 7043
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
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
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
Reputation: 3709
Company
has_many :transactions
Category
has_many :transactions
Transaction
belongs_to :category
belongs_to :company
Add resources :categories out side.
Upvotes: 0