Reputation: 1499
In my table professional_infos table there is one column primary_skill_ids which stores an array of skills for particular user. I want to list all the user who has some particular skill sets. example -
user1 has primary_skill as ["1","3","5","9","4"]
user2 has primary_skill as ["1","7","9","4"]
user3 has primary_skill as ["1","4","11"]
user3 has primary_skill as ["7","9","4"]
user4 has primary_skill as ["1","7","9"]
user5 has primary_skill as ["7","9"]
now I want to perform a search like get me all the users which have any or all of the skill primary_skill_ids as ["1","4]
please help me to write a rails query to do so.
I have done like the following
wildcard_search = "%#{params[:search_title]}%"
# key skills and best in search
@key_skills=[]
@key_skills.each do | sk |
# here I am thinking of looping through the ids and do a where clause on column primary_skill_ids but dont know its good idea
end
Upvotes: 1
Views: 93
Reputation: 1451
PostgreSQL supports standard SQL arrays and the standard any operation syntax:
So, you can use an SQL like
where name ilike any (array['%val1%', '%val2%'])
Using Rails it can be written like:
User.where('primary_skill ilike any (array[?])', ["1","4"] )
Additional info:
In your situation you can use "ILIKE", or "LIKE", but the difference is:
Usage of wildcards (%
from '%val1%'
) are detailed here
Upvotes: 0
Reputation: 102036
Serializing relation data in a string column violates the very idea of a relational database - which is that you have foreign key columns that point to other tables. Using array* or string types in the DB for associations is a really bad idea:
Instead you want to create a many-to-many association through a join table:
class User < ApplicationRecord
has_many :user_skills
has_many :skills, through: :user_skills
end
class Skill < ApplicationRecord
has_many :user_skills
has_many :users, through: :user_skills
end
class UserSkill < ApplicationRecord
belongs_to :user
belongs_to :skill
end
In this example we are using a table named user_skills
to join the two models:
create_table "user_skills", force: :cascade do |t|
t.integer "user_id"
t.integer "skill_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["skill_id"], name: "index_user_skills_on_skill_id", using: :btree
t.index ["user_id"], name: "index_user_skills_on_user_id", using: :btree
end
You can then setup UI controls by using the collection helpers:
# app/views/users/_form.html.erb
<%= form_for(@user) do |f| %>
<%= f.collection_check_boxes :skill_ids, Skill.all, :id, :name %>
<% end %>
# app/controllers/users_controller.rb
class UsersController < ApplicationController
# POST /users
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render :new
end
end
# PUT|PATCH /users/:id
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
else
render :edit
end
end
def user_params
params.require(:user)
.permit(skill_ids: [])
end
end
Upvotes: 3