2017-09-04 78 views
0

在我的表professional_infos表中有一列primary_skill_ids,它存儲了特定用戶的一組技能。我想列出具有某些特定技能集的所有用戶。 例子 -搜索在存儲數組的列中

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"] 

現在我要執行像讓我所有有任何或全部的技能primary_skill_ids作爲用戶搜索[「1」,「4]

請幫我寫一軌查詢到這樣做。

我已經做了類似下面的

 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 
+4

您應該使用[多對多關係](http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association)。 – Stefan

+0

我在做搜索功能。我已經定義了professional_infos和技能之間的關聯 –

+1

您可以展示您的模型和/或數據庫模式嗎? _「存儲一系列技能的一列primary_skill_ids」_聽起來更像是序列化字符串,而不是關聯。 – Stefan

回答

3

在字符串列序列化關係數據違反了關係型數據庫的想法 - 這是你有外鍵列指向其他表。在數據庫中使用數組*或字符串類型進行關聯是非常糟糕的主意:

  • 與包含整數或uiids的索引列相比,搜索字符串的效率非常低。
  • 沒有外鍵約束強制引用完整性。
  • 它並不是ActiveRecord的工作原理 - 這意味着您將通過與框架對抗來浪費時間。

相反,你要創建一個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 

在這個例子中,我們使用了一個名爲user_skills表加盟兩種模式:

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 

然後,您可以設置UI控件通過使用收集助手:

# 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 
+0

您必須創建一個遷移或rake任務來遍歷現有記錄並拆分字符串併爲每個記錄創建一個聯接錶行。如果您需要該任務的幫助,請將其作爲一個單獨的問題,並確保包含架構和任何相關信息。 – max