3

I'm creating a web application similar to LinkedIn using Ruby on Rails (rails 4), and I'm trying to add a "skills" column in the User table. Each user can have multiple skills, I want to be able to categorize users by skills.

I could either have the "skills" column be of type array (a string array, to be exact), or I could have a new model for skills and make associations (using has_many). Which would be better, or is there a nicer solution?

Thanks!

user3104471
  • 305
  • 1
  • 2
  • 11
  • 3
    I would suggest the skills model... it gives you the advantage of easily collating all users with a given skill. – SteveTurczyn Jul 17 '14 at 20:14
  • typist == Skill.find_by_name("typing"); typist.users – SteveTurczyn Jul 17 '14 at 20:15
  • What database system are you using? Nosql solutions support this pretty easily, otherwise you can store arrays or hashes in some DB systems like Postgres. Though I agree with @SteveTurczyn and use a different model – alalani Jul 17 '14 at 20:15
  • Maybe you can try this: https://github.com/mbleigh/acts-as-taggable-on it uses the second approach (model for skills) but lets you to use as your first approach (an string) – Aguardientico Jul 17 '14 at 20:41

2 Answers2

5

You should definitely go with the Model-based Skill solution instead of a serialized Array or any other solution:

  • You can find easily Users from one/several Skill (with serialized array, that's a big adventure)
  • Better standards between the differents skills in your DB:
    • with serialized Array, you cannot really control the case-sensitivity, typo errors, etc.
    • with a Skill model, you can easily implement a search-alike method (kind of like how Stackoverflow deals with the Tags about your post), tons of gems already exist for that purpose

The global relation config would be like :

class User < ActiveRecord::Base
  has_many :users_skills
  has_many :skills, through: :users_skills

class UsersSkill < ActiveRecord::Base
  belongs_to :user
  belongs_to :skill
  validates :user_id, :skill_id, presence: true

class Skill < ActiveRecord::Base
  has_many :users_skills
  has_many :users, through: :users_skills

With this, very easy to find Users from Skill, and vice-versa:

web_developpers = Skill.where(name: 'Web developper').first.users
johns_skills = User.where(name: 'John').first.skills

What if tomorrow your boss want you to add a feature like "preferred skill" or "best skill"? Or just a way to "order" (set a hierarchy between) a User's skills?

Just add a boolean column best on the join table (users_skills)

User.first.skills.where(users_skills: { best: true })
MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
0

Are you using Postgresql?

Then you can use the JSON data type

I wrote a question and an answer for it here:

Postgres JSON data type Rails query

You can have column skills

With JSON within it as {skills: [1,2,3,4]}

Community
  • 1
  • 1
Mohamed El Mahallawy
  • 13,024
  • 13
  • 52
  • 84