1

在这里,我有一段代码应该根据我对 Ruby 中字符串插值的了解来工作。它在模型类中:“s3_file”

基本上我想要完成的是在将文件保存到 AWS S3 时,我想将它们保存在运行时使用以下字符串插值创建的文件夹下。我正在使用 Devise 和 cancan 作为授权和身份验证 gem

下面的代码有效:

 Paperclip.interpolates :prefix  do |attachment, style|
    "#{Date.today.to_s }/system"
 end

 has_attached_file(  :upload,
                  :path => ":prefix/:basename.:extension",
                  :storage => :s3,
                  :s3_credentials => {:access_key_id => "XXX",
                                      :secret_access_key => "XXX"},
                  :bucket => "XXX"
                )

但是,我正在尝试获取用户电子邮件并将其插入回形针块中。此代码无法按预期工作。此代码的结果并非异常,但 @curr_user_email 始终为空,因此 AWS S3 上的文件夹没有名称。但是该方法确实创建了一个文件夹。我该如何纠正?

这段代码仍然不起作用

if(@curr_user_signed_in)
  @aPrefix = "#{Date.today.to_s }/#{@curr_user_email}"
else
  @aPrefix = "#{Date.today.to_s }/system"
end

Paperclip.interpolates :prefix  do |attachment, style|
   @aPrefix
end


has_attached_file(  :upload,
                  :path => ":prefix/:basename.:extension",
                  :storage => :s3,
                  :s3_credentials => {:access_key_id => "xxx",
                                      :secret_access_key => "xxx"},
                  :bucket => "xxx"
                )

在我的控制器中,我有这段代码:

  def index
   @s3_files = S3File.all

   @curr_user_signed_in = false
   if(user_signed_in?)
     @curr_user_signed_in = true
     @curr_user_email = current_user.email
   end
   respond_to do |format|
     format.html # index.html.erb
     format.json { render json: @s3_files }
   end
  end

所以真正的问题是这些@curr_user_signed_in = true @curr_user_email = current_user.email 被设置并且不为空,但由于某种原因它们不能被读入回形针块

4

1 回答 1

2

看起来你需要使用回形针插值。真的要归功于这个家伙:

https://stackoverflow.com/a/852768/931209

这是我认为应该可以解决您的问题的片段。

    # interpolate in paperclip
    Paperclip.interpolates :maybe_user  do |attachment, style|
      @prefix =  "#{Date.today.to_s }/system/"
      if(user_signed_in?)
      {
        @prefix = "#{Date.today.to_s }/#{current_user.id}/"
      }
      @prefix
    end 

然后...

     has_attached_file(:upload,
              :path => ":maybe_user/:basename.:extension",
              :storage => :s3,
              :s3_credentials => {:access_key_id => "XXXXX",
                                  :secret_access_key => "XXX"},
              :bucket => "XXX"
            )

这是回形针网站上的文档:

https://github.com/thoughtbot/paperclip/wiki/interpolations

希望有帮助!

编辑:如果这给了你任何麻烦,只需.to_s在字符串中添加一个,我认为你应该没问题。虽然,我不知道为什么会这样。

更新 -- 7/7 -- 内容从下面开始

前言:我没用过devise。

无法从模型中访问设计中的 current_user 方法。它仅在控制器中可用。

https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/helpers.rb#L33

您需要将 attr_accessor 添加到模型(S3File?)到当前用户,然后在模型中引用该实例变量。

控制器:

class S3FileController < ApplicationController

    def create
        s = S3File.new

        if user_signed_in?
            s.current_user = current_user
        else
            s.current_user = nil
        end

        # Alternatively written
        # user_signed_in? ? s.current_user = current_user : s.current_user = nil

        s.upload = params[:file]
        s.save

    end

end

模型:

class S3File < ActiveRecord::Base

    attr_accessor :current_user

    Paperclip.interpolates :maybe_user  do |attachment, style|
      @prefix =  "#{Date.today.to_s }/system/"
      if(@current_user)
      {
        @prefix = "#{Date.today.to_s }/#{current_user.id}/"
      }
      @prefix
    end 

end

我相信这应该可以工作,因为回形针在保存 S3File 之前没有处理文件。然后,您可以通过访问 User 对象,@current_user这样您就可以对插值执行类似的操作:

Paperclip.interpolates :prefix  do |attachment, style|
   @pre = "#{Date.today.to_s}/system"
   if(@current_user)
     @pre = "#{Date.today.to_s}/#{@current_user.email}"
    end
    @pre
end

有几点需要注意:

1.) 神奇之处在于attr_accessor :current_user它允许您将 current_user 对象的值存储到 S3File。如果您想存储更多信息,您可以添加任意数量的其他 attr_accessors。

2.) 并不是说​​它可能没有用例,但一般来说,您不想从模型中访问控制器可用的方法......这有点违反 MVC 的原则,因为身份验证应该在控制器中完成,而不是在模型中。我是根据我自己的经验这么说的,我很久以前就试图用authlogic我的(失败的)结果来做到这一点。YMMV,这只是思考的食物。

3.)我很确定你必须在回形针块内进行所有插值。也没有太多理由不这样做。

[附录]

4.) 控制器中设置的实例变量对模型不可用。它们的范围仅限于创建它们的类...这就是我使用 attr_accessor =) 的原因

[/附录]

希望这能让你更进一步!祝你好运。

于 2012-07-06T23:36:31.150 回答