rails 5 algolia搜索-按用户状态过滤结果

时间:2018-09-28 12:33:48

标签: ruby-on-rails devise ruby-on-rails-5 algolia

我正在尝试根据当前用户是否具有“管理员”身份来过滤使用algolia gem显示的搜索结果。

所有用户都可以创建客户,但是“管理员”用户可以访问所有客户,无论他们是否由该用户创建。我还在我的“用户”模型中使用devise gem。

客户控制器:

def index
  if current_user.admin
    @customers = Customer.all.order(id: :desc).paginate(:page => params[:page], :per_page => 4)
  else
    @customers = Customer.where(user: current_user).order(id: :desc).paginate(:page => params[:page], :per_page => 4)
  end
end

我正在使用algolia rails gem在customers#index中按客户进行搜索

搜索JS:

<!-- Algolia search JS -->
<script>
  var client = algoliasearch('x', 'x');
  var index = client.initIndex('Customer');
  //initialize autocomplete on search input (ID selector must match)
  autocomplete('#aa-search-input',
{ hint: false }, {
  source: autocomplete.sources.hits(index, {hitsPerPage: 5}),
  //value to be displayed in input control after user's suggestion selection
  displayKey: 'name',
  //hash of templates used when rendering dataset
  templates: {
      //'suggestion' templating function used to render a single suggestion
      suggestion: function(suggestion) {
        return `<span>${suggestion.first_name.value}"</span>` +;
      }
    }
  });
</script>

我需要做的是根据登录的用户是否是“管理员”用户来过滤自动完成建议。这只需要过滤该特定会话的索引,以使同时登录的多个用户不会影响其他用户可用的客户索引。

2 个答案:

答案 0 :(得分:0)

根据设计,Algolia不是关系数据库。

它不知道哪个user has_many customers或那个customer belongs_to user。它还不具备Devise知识,并且用户是管理员。

要在Algolia中复制此关系,必须创建一个“平面对象”,将其保留在属性中。

例如,您的“客户”索引可以包含记录,其中某个属性列出了可以查看它们的人。您可以将其命名为viewable_byuser_ids,随心所欲(如果没有“用户”索引,则可以是数据库中的id,无论如何): / p>

// sample Customer record in Algolia
{
    "name": "Ricky Bobby",
    "viewable_by": [1, 55, 278]
}

接下来,我将依靠您从Rails传递您的current_user.admin(是/否)和用户id,以便您可以在JS条件中引用它。

然后在自动完成中创建一组条件参数。如果current_user.adminfalse,则对用户id进行过滤:

<!-- Algolia search JS -->
<
script >
  var client = algoliasearch('BFBCTI275G', '5818cd87afb6c0ef5e4d5ec4ed6580d0');
var index = client.initIndex('Customer');

// create variable
var srcParams = {
  hitsPerPage: 5
}

// conditionally set filter based on admin
// your job to get admin boolean and user id into JS
if (!current_user.admin) {
  srcParams.filters = 'viewable_by: current_user.id';
}

autocomplete('#aa-search-input', {
  hint: false
}, {
  // use the srcParams
  source: autocomplete.sources.hits(index, srcParams),
  displayKey: 'name',
  templates: {
    suggestion: function(suggestion) {
      return `<span>${suggestion.first_name.value}"</span>` + ;
    }
  }
}); <
/script>

答案 1 :(得分:0)

解决了!解决方法如下: 我在“客户”索引中创建了“ user_id”记录:

Customer.rb

attribute :user_id do
  user.id if user
end

然后我使用SrcParams.filter根据user_id过滤结果:

JS文件

var client = algoliasearch('x', 'x');
var index = client.initIndex('Customer');
let admin = document.getElementById("admin-field").innerText; // returns "true" for admins
let userId = parseInt(document.getElementById("id-field").innerText); // returns the integer value of the user's id

var srcParams = { hitsPerPage: 5}

// conditionally set filter based on admin
if (admin != "true") {
  srcParams.filters = `user_id=${userId}`;
}

autocomplete('#aa-search-input', {
  hint: false
}, {
  // use the srcParams
  source: autocomplete.sources.hits(index, srcParams),
   displayKey: 'name',
  templates: {
    suggestion: function(suggestion) {
    console.log(srcParams);
    return  `<span>${suggestion.first_name.value}"</span>` ;
    }
  }
});