1

私のRailsアプリケーションでは、Searckick(elasticsearch)で高度な検索を設定しようとしています。私がしようとしていることは次のとおりです:searchkickで高度な検索を設定し、複数のモデルとの関連付け(Rails)

  • ユーザ、ロケーション、能力について検索し、常にユーザプロファイルを結果として戻すことができます。

私はこれまでユーザーに検索することができますが、これらの他のモデルでも検索する方法がわかりません。

私のルートは:

Rails.application.routes.draw do 
    ActiveAdmin.routes(self) 
    devise_for :users, controllers: {sessions: "sessions", registrations:  
    "registrations"} 
    # For details on the DSL available within this file, see 
    http://guides.rubyonrails.org/routing.html 

    root 'pages#home' 

    get "/news", to: 'pages#news' 

    get "welcome_back", to: 'pages#welcome_back' 

    get "/profile", to: "profile#show" 

    resources :profiles do 
    collection do 
     get :autocomplete 
    end 
    end 

    namespace :profile do 
    resources :locations 
    resources :positions 
    resources :competences 
    end 
end 

ユーザロケーションに属し、結合テーブルを介して複数のコンピタンスを有しています。言い換えれば、ユーザーはlocation_idを持っていて、あなたはそのユーザーが持っているusers_competencesを知るために、あなたの.competencesを呼び出すことができます。

誰でもこの検索を設定する方法を教えてもらえますか?

マイプロファイルコントローラ:

class ProfilesController < ApplicationController 

    def index 
    query = params[:search].presence || "*" 
    @users = User.search(query, suggest: true, operator: "or") 
    end 

    def autocomplete 
    render json: ["Test"] 
    end 

end 

私は私のモデルでデフ自己(検索)で動作するようにしようとしているが、これは動作しません。私が試した何

def self.search(search) 
     where(["User.first_name LIKE ?","%#{search}%"]) 
     where(["User.last_name LIKE ?","%#{search}%"]) 
     where(["User.competences.collect{&:name} IN ?","%#{search}%"]) 
     joins(:location).where("location.name LIKE ?", "%#{search}%") 
    else 
     all 
    end 
    end 

答えて

1

TL; DRは、現在お使いのコードで定義された検索インデックス

self.searchをカスタマイズするsearch_dataメソッドを定義が間違っている あなたself.search方法は次のようになりますActiveRecordとあなたが使っているデータベースを検索する方法。 Searchkickで検索する方法ではありません。 Searchkickについては

あなたはユーザー属性、コンピテンシー、および場所については検索に一致するユーザープロファイルを返すようにしたいなら、あなたはあなたがsearch_dataメソッドを使用してカスタムマッピングを経由して検索するユーザー属性、コンピテンシー、および場所を定義する必要があります、hereを文書化:

class User < ActiveRecord::Base 
    searchkick locations: ["location"] 
    # this line will eager load your assocations 
    scope :search_import, -> { includes(:location, :competences) } 

    def search_data 
    { 
     first_name: first_name, 
     last_name: last_name, 
     competences: competences.map(&:name), 
     # from your code above it looks like you want to search location.name 
     location_name: location.name 
     # the following merged hash would allow you to search by location latitude and 
     # longitude coordinates if you have them 
     ## if you don't use latitude and longitude then you don't need to include 
     ## `locations: ["location"] when you call searchkick in the User model on line 2 
     ## above or the merged location hash below 
    }.merge(location: {lat: location.latitude, lon: location.longitude}) 
    end 
end 

Profiles#indexアクションで検索クエリが動作します:

@users = User.search(query, suggest: true, operator: "or") 

定義したメソッドself.searchの必要はありません。

その他の注意

  • 私はあなたが正しくあなたのユーザモデルの提案を定義したクエリでsuggest: trueを含むので、想定しています

    class User < ActiveRecord::Base 
        searchkick locations: ["location"], suggest: [:first_name, :last_name, :location_name] # or whatever fields you want 
    end 
    
  • reindex
  • に確認してくださいますので、 Userのオブジェクトを返したい場合は、のインデックスを作成する必要はありませんまたはCompetenceモデル(上記のコードから、以前に行ったかどうかわからない)
関連する問題