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:install
Then, add an attachment, as usually do, using paperclip.
$ rails generate paperclip user avatar
Inside 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
end
Usage
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
end
Using 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
end
Using 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'
end
Then, 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
end
or 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
end
If you execute
has_attached_upload
method 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
end
And 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
end
Creating 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/base
You 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
end
and 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_identifier
instead justupload
orupload_identifier
to 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.