Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4: how to implement a column with multiple elements

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!

like image 653
user3104471 Avatar asked Dec 07 '25 09:12

user3104471


1 Answers

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 })
like image 138
MrYoshiji Avatar answered Dec 09 '25 23:12

MrYoshiji