Here I have a piece of code that should work based on what I know of string interpolation in Ruby. Its inside a model class: “s3_file”
Basically wahat I am trying to accomplish is while saving a file to AWS S3, I would like to save them under a folder thats created at runtime using the following string interpolations. I am using Devise and cancan as authorization and authentication gems
the code below works:
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"
)
But, I am trying to get the usersemail and insert that into the Paperclip block. This code doesn’t work as desired. The result of this code is not an exception but @curr_user_email is always null and as a result the folder on AWS S3 has no name. But the method does create a folder. How can I correct this?
THis code still does not work
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"
)
In my controller I have this bit of code:
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
So the real problem is that these
@curr_user_signed_in = true
@curr_user_email = current_user.email
are being set and are not null, but for some reason they cannot be read into the paperclip block
Looks like you need to use paperclip interpolates. Credit really goes to this fellow:
https://stackoverflow.com/a/852768/931209
And here’s a snippet I believe should solve your problem.
then…
Here’s the doc on the paperclip website:
https://github.com/thoughtbot/paperclip/wiki/interpolations
Hope that helps!
Edit: If that gives you any shit, just add a
.to_sto the strings and I think you should be alright. Though, I don’t know why it would.Update — 7/7 — Content Starts Below
Preface: I have not used devise.
The current_user method from devise cannot be accessed from within the model. It’s only available in the controllers.
https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/helpers.rb#L33
You’ll need to add an attr_accessor to the model (S3File?) to current user, and then reference that instance variable within the model.
Controller:
Model:
I believe this should work as paperclip isn’t processing the file before S3File is saved. You then have access to the User object via
@current_userso you can do something like this for the interpolation:A couple of things to note:
1.) The magic is really from the
attr_accessor :current_userwhich allows you to store the value of the current_user object to the S3File. You can add as many other attr_accessors as you’d like if you want to store more information.2.) Not that there may not be a use case for it, but generally speaking, you don’t want to access methods available to your controllers from within the model… It sort of breaks the principles of MVC, as authentication should be done in the controllers, not in the model. I say this from my own experience having tried to do this long ago with
authlogicand my (failed) results. YMMV, it’s just food for thought.3.) I’m pretty sure you have to do all the interpolation inside the paperclip block. There isn’t much of a reason not to either.
[addendum]
4.) Instance variables set in the controller are not available to the models. They are scoped to the class they’re created in… which is why I used attr_accessor =)
[/addendum]
Hopefully this gets you a few steps closer! Good luck.