Elasticsearch,Chewy,Postgres和Apartment Multi-Tenancy

时间:2015-08-17 19:54:45

标签: ruby-on-rails postgresql elasticsearch multi-tenant apartment-gem

我有一个带有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')

暂时解决了佣金问题,但它让我对弹性搜索以及一般的耐摔和多租户有了更大的思考。耐嚼有没有任何形式的实施?如果没有,你有什么建议吗?

2 个答案:

答案 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