At the time ClassroomParent was started, the file_column plugin was the state of art for uploads. Not only did it integrate nicely with rmagick, but there was also a bridge for active_scaffold.
But file_column has been left behind by many excellent plugins/gems, most notably,
paperclip.
In 2008,
Mark Cornick wrote an excellent blog on how to migrate from file_column to paperclip. For the most part, I have followed his instructions, though I split his single migration into several.
One major hurdle I had to overcome was that my file storage path is dynamically generated. This is so I can better segregate one school's assets from another.
Looking at the paperclip documentation, they state that the attributes associated with has_attached_file can accept a lambda, so I tried this on the :path attribute:
:path => lambda { |attachment| "/system/#{attachment.instance.sub_domain}/:class/:id/:basename.:extension"
This worked for the path value, but when I tried to access the url value, I got the following error:
NoMethodError: undefined method `gsub' for #<Proc:0x000001058f79a0>
from /Users/user/.rvm/gems/ruby-1.9.2-p180@classroom_parent/gems/paperclip-2.5.2/lib/paperclip/interpolations.rb:33:in `block in interpolate'
from /Users/user/.rvm/gems/ruby-1.9.2-p180@classroom_parent/gems/paperclip-2.5.2/lib/paperclip/interpolations.rb:32:in `each'
Looking at the paperclip code, I could see the offending gsub statement, and it did not look easy to work around it.
However, there was a little note, that I don't believe is echoed in the paperclip gems readme, that states that a symbol can be passed to the path attribute that references an instance method. Moving my code from the lambda to a public private method, and using that method name as the value passed to the path attribute worked like a charm.
:path => :path_to_file
def path_to_file
return "/system/#{sub_domain}/:class/:id/:basename.:extension"
end
private
def sub_domain
...code to get to the sub_domain of the school
end
Thanks for solution. It works for me.
ReplyDeleteBut I used a private method to return the path.
Prodis: That does make more sense. I have done the same and will edit the blog to match.
ReplyDeleteThanks for this, I still had problems with gsub when using it for :path but found the interpolate solution works a charm http://stackoverflow.com/a/11067061/409023
ReplyDeleteThanks! Saved my day.
ReplyDelete