I have a design question: Is it always best practice to pair a belongs_to association with a matching has_many?

Context:

I am building a quiz feature in an application. Passing the quiz involves a user making the correct series of choices to complete a correct “path.” Some paths are valid sequences. Others are not.

As a result the QuizPath model/table is essentially just a set of foreign_keys + belongs_to associations with an additional :status enum.

class QuizPath < ApplicationRecord belongs_to :user belongs_to :manufacturer belongs_to :vehicle_class belongs_to :model belongs_to :trim belongs_to :color enum status: [:incomplete, :invalid, :valid] end 

For a variety of reasons the belongs_to relationships are necessary. However, only the User represents a meaningful has_many relationship that is a likely entry point to accessing or querying for a QuizPath.

As a result it feels like clutter to add inverse has_many relationships to all the other models that are essentially irrelevant from a business logic perspective. On the other hand, I am not sure it is good practice from an ActiveRecord perspective to omit them.

What do you consider best practice here?

Edit:

I will add here that in the particular case of this quiz, the referenced associations other than the user are to essentially immutable data (manufacturer, model, etc). Managing dependent: nullify/destroy is probably less of a critical concern here than might otherwise be the case, but still a relevant point.

Edit again: currently on Rails 5.2.x

2 Answers

It is considered a best practice, but only because of Active Record magic. From the Rails guide on Bi-Directional Associations:

"Active Record will attempt to automatically identify that these two models share a bi-directional association based on the association name. In this way, Active Record will only load one copy of the Author object, making your application more efficient and preventing inconsistent data:"

Yes it is really best practice however I would only add what you want or need, but remember, by not adding a corresponding association you may find that at some point in the future you will be bitten by the assumption that you have done so. You may also find that Rails behaves mysteriously as ActiveRecord will attempt to automatically identify the two way relationship

But of course there are also other options such as has_one and has_many_through which may come in use for say finding all quizes that mention a specific manufacturer allowing you to check for duplicates.

If you are worried about cluttering up your models you could always put the code in an include file

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.