rails 5 algolia 搜索 - 按用户状态过滤结果
rails 5 algolia search - filter results by user status
我正在尝试根据当前用户是否具有 'admin' 身份来过滤使用 algolia gem 显示的搜索结果。
所有用户都可以创建客户,但是 'admin' 用户可以访问所有客户,无论它们是否由该用户创建。我也在为我的 'users' 模型使用设计 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
我正在使用算法 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>
我需要做的是根据登录用户是否是 'admin' 用户过滤自动完成建议。这需要只过滤该特定会话的索引,以便同时登录的多个用户不会影响其他用户可用的客户索引。
按照设计,Algolia 不是关系数据库。
不知道是哪个user has_many customers
,还是那个customer belongs_to user
。它也不知道 Devise 并且用户是管理员。
要在 Algolia 中复制这种关系,您必须创建一个 "flat object" 来保存属性中的关系。
例如,您的 "Customer" 索引可能包含记录,其中的属性列出了哪些人可以查看这些记录。您可以将其命名为 viewable_by
或 user_ids
,任何您想要的名称(如果您没有 "User" 索引,那么这些可能是您数据库中的 id
,随便什么都行) :
// sample Customer record in Algolia
{
"name": "Ricky Bobby",
"viewable_by": [1, 55, 278]
}
接下来,我就靠你把你的current_user.admin
(true/false)和用户id
从Rails传递过来,这样你就可以在JS中引用了有条件的。
然后在自动完成中创建一组条件参数。如果 current_user.admin
是 false
然后过滤用户 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>
已解决!解决方案如下:
我在“客户”索引中创建了一条 '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>` ;
}
}
});
我正在尝试根据当前用户是否具有 'admin' 身份来过滤使用 algolia gem 显示的搜索结果。
所有用户都可以创建客户,但是 'admin' 用户可以访问所有客户,无论它们是否由该用户创建。我也在为我的 'users' 模型使用设计 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
我正在使用算法 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>
我需要做的是根据登录用户是否是 'admin' 用户过滤自动完成建议。这需要只过滤该特定会话的索引,以便同时登录的多个用户不会影响其他用户可用的客户索引。
按照设计,Algolia 不是关系数据库。
不知道是哪个user has_many customers
,还是那个customer belongs_to user
。它也不知道 Devise 并且用户是管理员。
要在 Algolia 中复制这种关系,您必须创建一个 "flat object" 来保存属性中的关系。
例如,您的 "Customer" 索引可能包含记录,其中的属性列出了哪些人可以查看这些记录。您可以将其命名为 viewable_by
或 user_ids
,任何您想要的名称(如果您没有 "User" 索引,那么这些可能是您数据库中的 id
,随便什么都行) :
// sample Customer record in Algolia
{
"name": "Ricky Bobby",
"viewable_by": [1, 55, 278]
}
接下来,我就靠你把你的current_user.admin
(true/false)和用户id
从Rails传递过来,这样你就可以在JS中引用了有条件的。
然后在自动完成中创建一组条件参数。如果 current_user.admin
是 false
然后过滤用户 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>
已解决!解决方案如下: 我在“客户”索引中创建了一条 '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>` ;
}
}
});