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

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 25, 2015 at 21:53
\$\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\$ 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\$ 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.

answered May 29, 2018 at 7:31
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.