5
\$\begingroup\$

I want to simplify my Rails models, current looks like this:

class User < ActiveRecord::Base
  has_many :offers, dependent: :destroy
  has_many :reviews, dependent: :destroy
  has_many :comments, dependent: :destroy
end

class Offer < ActiveRecord::Base
  belongs_to :user
  has_many :documents, as: :documentable
  has_many :comments, dependent: :destroy
  has_many :reviews, dependent: :destroy
end

class Review < ActiveRecord::Base
  belongs_to :user
  belongs_to :offer
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :offer
end

class Document < ActiveRecord::Base
  belongs_to :documentable, polymorphic: true
end

As you can see, I have the same relations on Comment and Review models, but they have some difference in columns, what are the options do I have to minimize the amount of models?

enter image description here

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Why the desire for fewer models? If a review is different from a comment, then let them be different models. Maybe share some code via modules/concerns, but I see no reason to conflate the two just for the sake of "fewer models" \$\endgroup\$
    – Flambino
    Commented Jan 26, 2015 at 1:44
  • \$\begingroup\$ @Flambino because I noticed duplication in Review and Comment models, and I was thinking that there's more elegant way of doing this \$\endgroup\$ Commented Jan 26, 2015 at 2:14
  • 1
    \$\begingroup\$ I'd say the most elegant way is to model your domain as best you can. If that means more models, then more models it is. Functionality-wise those models can share code (e.g. modules/concerns); less code is a good thing, but fewer models isn't a goal in and of itself. As long as a comment is somehow not the same as a review, and vice-versa, don't try to make it one-size-fits-all. It's more likely to end up as one-size-fits-none. And should the two diverge more in functionality later, you'll want distinct models anyway. \$\endgroup\$
    – Flambino
    Commented Jan 26, 2015 at 12:18

1 Answer 1

1
\$\begingroup\$

First thing is if they are different treat them different. You can share code with help of interaction or service of some other way may be with active active_interaction. But if you really want to have less table then you may define one single model say Content and this will have a column content_type: integer with default value as 0 and all your other columns then convert the content_type to enum something like below

class Content < ApplicationRecord
  enum content_type: { comment: 0, rating: 1 }
end

this will help you to differentiate between comment and rating. With proper indexing it will make no issue.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.