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"
                )

しかし、ユーザーのメールを取得して、それを Paperclip ブロックに挿入しようとしています。このコードは期待どおりに機能しません。このコードの結果は例外ではありませんが、@curr_user_email は常に null であるため、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 が設定されており、null ではないことですが、何らかの理由でそれらを paperclip ブロックに読み込むことができないことです

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"
            )

ペーパークリップ Web サイトのドキュメントは次のとおりです。

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

それが役立つことを願っています!

編集:それで問題が発生した場合は、文字列に a を追加するだけで.to_s問題ないと思います。とはいえ、なぜそうなるのかはわかりません。

更新 -- 7/7 -- 内容は以下から

序文:私はデバイスを使用していません。

devise の current_user メソッドは、モデル内からアクセスできません。コントローラーでのみ使用できます。

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

モデル (S3File?) に attr_accessor を現在のユーザーに追加し、モデル内でそのインスタンス変数を参照する必要があります。

コントローラ:

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.) paperclip ブロック内ですべての補間を行う必要があると確信しています。どちらもしない理由はあまりありません。

【追記】

4.) コントローラーで設定されたインスタンス変数は、モデルでは使用できません。それらは作成されたクラスにスコープされます...それが私が attr_accessor =) を使用した理由です

【追記】

うまくいけば、これで数歩近づくことができます!幸運を。

于 2012-07-06T23:36:31.150 に答える