DEPRECATED - no longer actively maintained
Rails Pallet
Rails engine to save paperclip attachments asynchronously. For example, if you have an User model with avatar paperclip attribute, you will:
- Create a new upload instance to hold the avatar file temporarily.
- Create a new user passing the upload id or instance as parameter.
Installation
Add to your Gemfile...
gem 'rails_pallet'Run the installer:
$ rails generate rails_pallet:installThen, add an attachment, as usually do, using paperclip.
$ rails generate paperclip user avatarInside User model, you need to execute has_attached_upload instead the has_attached_file paperclip's method:
class User < ActiveRecord::Base
has_attached_upload :avatar, path: ':rails_root/tmp/users/:id/:filename'
do_not_validate_attachment_file_type :avatar
endUsage
Using upload_identifier
First: you need to save an upload instance.
The engine creates the POST /uploads endpoint to achieve this.
After perform a POST to /uploads with a file param, you will get this response:
{
"upload": {
"identifier": "rW6q2QZM",
"file_extension": "jpg",
"file_name": "90033441_BLO_20150607",
"download_url": "http://my-server.com/uploads/rW6q2QZM/download"
}
}Second: supposing you have an UsersController, you need to perform a POST /users to create a new user passing the upload identifier you get previously.
class UsersController < ApplicationController
def create
respond_with User.create(permitted_params)
end
private
def permitted_params
params.require(:user).permit(:upload_identifier)
end
endUsing upload
You can do something like this:
class UsersController < ApplicationController
def create
@user = User.new
@user.upload = RailsPallet::Upload.create(file: params[:file])
@user.save!
respond_with @user
end
endUsing prefix
You will need a way to match an upload resource with a specific attribute if you have two or more paperclip attributes on the same model. To do this, you can pass the option upload: { use_prefix: true } on has_attached_upload like this:
class User < ActiveRecord::Base
has_attached_upload :avatar, path: ':rails_root/tmp/users/:id/:filename', upload: { use_prefix: true }
has_attached_upload :document, path: ':rails_root/tmp/users/:id/:filename', upload: { use_prefix: true }
has_attached_upload :photo, path: ':rails_root/tmp/users/:id/:filename'
endThen, in your controller...
class UsersController < ApplicationController
def create
respond_with User.create(permitted_params)
end
private
def permitted_params
params.require(:user).permit(:avatar_upload_identifier, :document_upload_identifier, :upload_identifier)
end
endor using the upload object...
class UsersController < ApplicationController
def create
@user = User.new
@user.avatar_upload = RailsPallet::Upload.create(file: params[:avatar])
@user.document_upload = RailsPallet::Upload.create(file: params[:document])
@user.upload = RailsPallet::Upload.create(file: params[:photo])
@user.save!
respond_with @user
end
endIf you execute
has_attached_uploadmethod two or more times in same model withupload: { use_prefix: false }(false is the default value), you will be obligated to use theupload: { use_prefix: true }option. If you don't, an exception will be raised.
Base64 Encoding
If you want to save base64 encoded attachments, you can execute the allow_encoded_file_for method:
class User < ActiveRecord::Base
has_attached_upload :avatar, path: ':rails_root/tmp/users/:id/:filename'
allow_encoded_file_for :avatar
do_not_validate_attachment_file_type :avatar
endAnd then...
class UsersController < ApplicationController
def create
respond_with User.create(permitted_params)
end
private
def permitted_params
params.require(:user).permit(:encoded_avatar)
# encoded_avatar param must hold the encoded file
end
endCreating your own UploadsController
You can generate your own UploadsController if for example:
- your controllers don't inherit from the
ApplicationController - you want to change the default route for
UploadsController. (Also you can map the default controller with another route in yourroutes.rb) - you want to add extra logic to the default
UploadsController
Running...
$ rails generate rails_pallet:upload_controller api/uploads api/baseYou will get in your_app/app/controllers/api/uploads_controller.rb
class Api::UploadsController < Api::BaseController
self.responder = RailsPalletResponder
respond_to :json
def create
new_upload = RailsPallet::Upload.create(permitted_params)
respond_with new_upload, status: :created
end
private
def permitted_params
params.permit(:file)
end
def upload
@upload ||= RailsPallet::Upload.find_by_identifier(params[:identifier])
end
endand the route...
post "api/uploads", to: "api/uploads#create", defaults: { format: :json }Configuration
You can change the engine configuration from your_app/config/initializers/rails_pallet.rb
Configuration Options:
-
hash_salt: The upload module uses a salt string to generate an unique hash for each instance. A salt string can be defined here to replace the default and increase the module's security. -
use_prefix: false by default. If true, you will need to pass[host_model_paperclip_attribute_name]_+upload|upload_identifierinstead justuploadorupload_identifierto the host model to use an upload resource.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request
Credits
Thank you contributors!
rails_pallet is maintained by platanus.
License
Rails Pallet is © 2017 Platanus, spa. It is free software and may be redistributed under the terms specified in the LICENSE file.