1

Oftentimes, I come across a situation that kind of irks me because I don't feel like my solution for it is up to par.

Say that I have a User model. There can be two TYPES of users - admins and the regular folk. In this particular case, I've simply split User and Admin into separate models - fair enough.

In some cases when there are numerous types of the same model (Foo can be green, red, purple, yellow, etc) I don't see much sense in dealing with 10 separate models like YellowFoo, GreenFoo, etc - so I add a "type" attribute to the model and then the code for, say, finding the correct object is simplified to User.where(:type => "some_type").

Is this an acceptable way of doing things in Ruby on Rails? Should the type be set to a be Symbol instead of a string so that User.where(:type => :some_type) looks prettier or is this a hack no matter how you look at it?

Same goes for views that I create. In the above example, there is an admin controller with a whole separate dashboard from the users, even though the code for the dashboard is more or less the same, with a few exceptions (but in the future, potentially far more different). Is this an acceptable way of doing things or the newb way?

Thanks in advance!

dsp_099
  • 5,801
  • 17
  • 72
  • 128
  • How about inheriting from models? Look at http://stackoverflow.com/questions/6429725/rails-model-inheritance – Bornfree Jul 03 '13 at 09:42

2 Answers2

1

I would suggest for different types/roles of users in our application, we can define a Role model.

We can define as the associations between User and Role as per our requirement. More basically, In Role Model we will define has_many :users

In User model we will define belongs_to :role

A role will have multiple users. We can check each users role in User model

def has_role?(roleSymbol)    
  (role.role_name.underscore.humanize.downcase.to_sym == roleSymbol)? true :false
end

Here we can check the user has a role of "Admin" or "Normal" user.

For view parts we can check the user roles and can include separate partial for different types of users.

Wally Altman
  • 3,535
  • 3
  • 25
  • 33
Debadatt
  • 5,935
  • 4
  • 27
  • 40
1

type attribute is good enough to use it inside the model to separate different types of objects. But type attribute name itself used by Rails AR class method, so I'd suggest to use model name specified field type name like 'user_type' for User model to avoid conflicts.

Having defined model's types you can add very handy model's scopes and methods.

For example:

class Order
  # I prefer to define type constants as camelized strings, but it would be probably 
  # better to use strings in downcase for localization purposes
  ORDER_TYPES = (OrderTypePersonal, OrderTypeOrganization = 'Personal', 'Organization')

  scope :personal,     where(order_type: OrderTypePersonal)
  scope :organization, where(order_type: OrderTypeOrganization)

  def personal?;    order_type == OrderTypePersonal     end
  def organization; order_type == OrderTypeOrganization end
end

# find all personal orders
personal_orders = Order.personal.all
# build new organization order
organization_order = Order.organization.new
# check order type
Order.find(14).personal?
# user order types as select
f.select :order_type, Order::ORDER_TYPES
BitOfUniverse
  • 5,903
  • 1
  • 34
  • 38
  • I don't really understand the part with scopes. Can you chew it out a bit more? – dsp_099 Jul 08 '13 at 14:38
  • @dsp_099 Quite often when you have the need to use different types on the mdoel, you will need to use scopes with based on these types for this model too. Scopes gives you very powerfull and handy possibilities thru `ActiveRecord::Relation` object. `organization_order = Order.organization.new` -> will return Order with type='Organization', for my opinion it often makes code more readable and easier to understand. – BitOfUniverse Jul 09 '13 at 08:59