我有一个带有rails 4.2.3和ruby 2.2.2的多租户rails-api项目。我发现有很多资源用于处理带有rails和postgres的多租户,但对于弹性搜索并不是很多,特别是有耐嚼的宝石。我发布了an issue on the chewy gem github page,我得到了一些很好的反馈,帮助我最终找到解决问题的方法。我认为,为了更大的利益而将它贴在这里也不会有什么坏处。以下是我的问题的细节。
我最近使用多个架构从MySQL切换到Postgres,并且遇到了rake chewy:reset:all
的问题。它看起来好像是默认的"公众"架构,但我想指定架构。我正在使用公寓宝石,所以我把它放在我的一个索引中:
Apartment::Tenant.switch!('tenant_name')
暂时解决了佣金问题,但它让我对弹性搜索以及一般的耐摔和多租户有了更大的思考。耐嚼有没有任何形式的实施?如果没有,你有什么建议吗?
答案 0 :(得分:0)
我创建了一个耐嚼的猴子补丁初始化器:
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil)
prefix = Apartment::Tenant.current
if suggest
@index_name = build_index_name(suggest, prefix: prefix)
else
@index_name = build_index_name(
name.sub(/Index\Z/, '').demodulize.underscore,
prefix: prefix
) if name
end
end
@index_name or raise UndefinedIndex
end
end
end
自定义佣金任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset:all'].invoke
end
end
end
由于我有一个完全独立的测试集群,我们不需要在索引前添加“test”,因此我使用当前租户名称重新定义了prefix
。据我现在所知,每次调用特定索引时,耐嚼都会遇到index_name
方法。然后它会抓取当前租户的正确用户索引。
答案 1 :(得分:0)
感谢Eli,让我朝着正确的方向前进。我已经用最新的耐嚼代码更新了Eli的代码。
# config/initializers/chewy_multi_tenancy.rb
module Chewy
class Index
def self.index_name(suggest = nil, prefix: nil, suffix: nil)
tenant_prefix = [Apartment::Tenant.current, prefix]
if suggest
@base_name = (tenant_prefix + [suggest.to_s.presence]).reject(&:blank?).join('_')
else
(tenant_prefix + [ base_name, suffix ]).reject(&:blank?).join('_')
end
end
end
end
和自定义耙任务:
# lib/tasks/elastic.rake
namespace :elastic do
desc "resets all indexes for a given tenant ('rake elastic:reset TENANT=tenant_name')"
task reset: :environment do
if ENV['TENANT'].nil?
puts "Uh oh! You didn't specify a tenant!\n"
puts "Example: rake elastic:reset TENANT=tenant_name"
exit
elsif !Apartment.tenant_names.include?(ENV['TENANT'])
puts "That tenant doesn't exist. Please choose from the following:\n"
puts Apartment.tenant_names
exit
else
Apartment::Tenant.switch!(ENV['TENANT'])
Rake::Task['chewy:reset'].invoke
end
end
end