2017-09-04 69 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