Reputation: 428
I have User model and Organization model. The only difference is that organization has_many users, all other properties are same. I don't want to put it in one table/model. How can I remove tons of code duplicating in this models? Should I use Concerns? I think, it will be not normal if User model will looks like :
class User < ActiveRecord::Base
include user_concern
end
So, how can I extend user model in other model? And how to generate this model with rails g
with all User's fields inside?
Upvotes: 1
Views: 199
Reputation: 10413
You could use single table inheritance (STI) for this. To get it to work, your model needs a type
-field of type string
, in which ActiveRecord stores the actual type of your record. Then, you just extend your base model for this.
migration
add_column :users, :type, :string
models
class User < ActiveRecord::Base
and class Organisation < User
.
ActiveRecord will now fill your type
-field with the model-name, and store both in your users
table (since this is the one the organisation model is inheriting from).
Have a look at the according section on http://api.rubyonrails.org/classes/ActiveRecord/Base.html .
However, in your case, I'd create a base model, e.g. Address
, and then extend User
and Organisation
from it, to maintain semantically correct models.
Upvotes: 0
Reputation: 7937
I would keep with concerns rather than using STI. STI often causes more problem that it solves (type mismatches, form urls, etc), plus inheritance won't make sense, here : an user is not a kind of company, and a company is not a kind of user.
I think your problem is a naming one. Obviously, your concern should not be "UserConcern". The question is : what kind of methods do you group in that concern ?
Are your methods about social relation between users ? Then, you need a Socializable
concern. Are they about subscribing to mailing list ? Then you need a Subscribable
concern.
It's ok to have several ones, even if they have a single method in it, because developers won't wonder "what the hell does this do ?" if all concerns are correctly named.
You should also probably let class level method calls out concerns.
If it's ok for scopes to be embedded in concerns (after all, they resolve in method definitions), it feels less natural to me to put relations in there.
It's ok to duplicate #has_many :foos
, we do it all the time in separate models, and it's already difficult enough to get an idea of table schema from a model without hiding more information.
Upvotes: 2