公寓宝石的回形针自定义路径

时间:2018-03-13 13:36:38

标签: ruby-on-rails amazon-s3 paperclip apartment-gem

使用Paperclip(使用s3存储)和Apartment gem时遇到非常有线的问题。

Apartment gem正在与Postgres DB一起用于多租户。 (即每个租户的单独模式)

对于存储,我想为每个租户创建一个单独的文件夹。

class Media < ApplicationRecord

  belongs_to :user

  has_attached_file :file,
          :storage => :s3,
          :s3_credentials => {
                  :access_key_id => "ACCESSKEY",
                  :secret_access_key => "SECRETE KEY"
                },
          :path => "#{Apartment::Tenant.current}/:class/:attachment/:id_partition/:style/:filename"


end

以上是我的媒体文件夹,属于用户。

class User < ApplicationRecord

  has_attached_file :avatar,
      :storage => :s3,
      :s3_credentials => {
              :access_key_id => "ACCESSKEY",
              :secret_access_key => "SECRETE KEY"
            },
      :path => "#{Apartment::Tenant.current}/:class/:attachment/:id_partition/:style/:filename"
end

Apartment.rb文件如下所示

require 'apartment/elevators/subdomain'
require 'rescued_apartment_middleware'

Apartment.configure do |config|
  config.excluded_models = %w{ Account }
  config.tenant_names = lambda { Account.pluck :subdomain }
  config.use_schemas = true
end

Rails.application.config.middleware.insert_before Warden::Manager, RescuedApartmentElevator
Apartment::Elevators::Subdomain.excluded_subdomains = ['www','admin']

rescued_apartment_elevator.rb文件如下所示

class RescuedApartmentElevator < Apartment::Elevators::Subdomain
  def call(env)
   begin
     super
   rescue Apartment::TenantNotFound
     env[:apartment_tenant_not_found] = true # to be later referenced in your ApplicationController
     @app.call(env) # the middleware call method should return this, but it was probably short-circuited by the raise
   end
 end
end

在application_controller.rb中,我处理了类似下面的代码

class ApplicationController < ActionController::Base
  before_action :load_schema, :authenticate_user!, :set_mailer_host
  before_action :configure_permitted_parameters, if: :devise_controller?

  private 

  def load_schema
    Apartment::Tenant.switch!
    return if request.subdomain == "www"

    if request.subdomain == "" 
      redirect_to root_url(subdomain: 'www')
    else 
      if current_account
        Apartment::Tenant.switch!(current_account.subdomain)
      else
        if request.env[:apartment_tenant_not_found]
         redirect_to root_url(subdomain: 'www'), notice: 'Account you are looking for do not exists'
        end
      end
    end
   end

end

我启动服务器,转到其中一个租户,例如http://apple.lvh.me:3000(苹果是租客名称)

1。如果我去编辑用户个人资料并上传用户个人资料的文件,     Apartment :: Tenant.current在模型中返回“public”,因此     该文件正在上传到公共文件夹而不是“苹果”     文件夹中。

我在下面使用devise gem(最新版本)是我的user_controller.rb的样子

class UsersController < ApplicationController
  before_action : set_user, only: [:edit,:update]

  def update
   if @user.update(user_params)
    if @user.pending_reconfirmation?
      redirect_to edit_user_path(current_user), notice: "Your profile is successfully updated! But if you changed the email address, then please confirm it before!"
    else
      redirect_to edit_user_path(current_user), notice: "Your profile is successfully updated!"
    end
  else
    render "edit"
  end
 end

end

问题2  **当我去媒体并添加一些媒体时,他们会正确地转到s3桶上的“apple”文件夹。我会签出,转到不同的tanent,http://google.lvh.me:3000/(谷歌是租户名称)。如果我去媒体列表,URL将继续指向Apartment :: Tenant.current - &gt;只有苹果。这会导致Google租户的错误网址和图片无法显示。

如果我关闭并重新启动服务器,则rails将开始返回google for Apartment :: Tenant.current方法,因此URL正确指向正确的文件夹。 **

夏季,下面是我的问题。

  1. 在回形针自定义路径的模型中使用Apartment :: Tenant.current - 这是对的吗?还有其他方法可以归还我 当前的tanent所以我可以用它在s3桶上创建文件夹。
  2. 我是否在我的apartment.rb文件中正确配置了中间件?
  3. 有不同的方法吗?

1 个答案:

答案 0 :(得分:1)

发布到StackOverflow后,我能够找到解决方案。将其发布在此处以防万一其他人将来发现此事。

我的错误是尝试直接使用#{Apartment :: Tenant.current}进入路径。这是错的。回形针支持插值,我应该使用它来生成动态路径。

以下是所需的更改。

has_attached_file :file,
                    :storage => :s3,
                    :s3_credentials => {
                      :access_key_id => "AccessKey",
                      :secret_access_key => "SecreteKey"
                    },
                    :path => ":tenant/:class/:attachment/:id_partition/:style/:filename"

请注意:路径中引入了租户。

将以下行添加到paperclip.rb

Paperclip.interpolates :tenant do |attachment, style|
  Apartment::Tenant.current
end

就是这样。希望它可以帮助别人!