We have implemented a mechanism to upload images directly from Rails to S3 on AWS.
So one question is, the implementation itself was completed without any problems, but the images are not uploaded from the local development environment to S3 on AWS.
We are considering using Heroku for the production environment, but currently it does not work in the local development environment.
Reference site: https://qiita.com/DaichiSaito/items/80e89f0c96d88afcc5ff
Reference site: https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails
Below is the actual code.
GemfileFg
gem'aws-sdk','~>2'
model/users.rb
class User</pre>
<pre><code>class UserAvatar</pre>
<pre><code>users_controller.rb
before_action: set_s3_direct_post, only: [: new,: edit,: create,: update] # Add
#User new registration form
def new
if current_user
redirect_to current_user
else else
@user_form = UserForm.new
end
end
#User edit form
def edit
@user_form = UserForm.new (User.find (params [: id]))
end
#Create new user
def create
@user_form = UserForm.new
@ user_form.assign_attributes (params [: form])
if @ user_form.save
@ user_form.user.send_activation_email
redirect_to: signup_thanks
else else
render: new
end
end
# User update
def update
@user_form = UserForm.new (@user)
@ user_form.assign_attributes (params [: form])
if @ user_form.save
redirect_to @ user_form.user
else else
render: edit
end
end
private
# add to
def set_s3_direct_post
@ s3_direct_post = S3_BUCKET.presigned_post (key: "uploads/# {SecureRandom.uuid}/${filename}", success_action_status: '201', acl:'public-read')
end
forms/user_form.rb
class UserForm
include ActiveModel :: Model
attr_accessor: user,: name,: email,: gender,: inputs_destroy
delegate: new_record ?,: persisted ?,: save, to:: user
def initialize (user = nil)
@user = user
@user || = User.new
@ user.build_avatar unless @ user.avatar.present?
end
def assign_attributes (params = {})
@params = params
user.assign_attributes (user_params)
if params [: user] [: avatar] .present?avatar = avatar_params.fetch (: avatar)
user.avatar.assign_attributes (avatar)
end
end
private
def user_params
@ params.require (: user) .except (: avatar) .permit (
: name,: email,: gender,: profile_text,: password,: password_confirmation
)
end
def avatar_params
@ params.require (: user) .slice (: avatar) .permit (
avatar: [: image]
)
end
end
views/users/edit.html.erb<% = form_for (@user_form, as:'form', url: @ user_form.user, html: {class:'directUpload', data: {'form-data' =>(@ s3_direct_post.fields),'url' =>@ s3_direct_post.url,'host' =>URI.parse (@ s3_direct_post.url) .host}}) do | f |%># Modify<script>$(function () {
$('.directUpload'). find ("input: file"). each (function (i, elem) {
var fileInput = $(elem);
var form = $(fileInput.parents ('form: first'));
var submitButton = form.find ('input [type = "submit"]');
var progressBar = $(" ");
var barContainer = $(" "). append (progressBar);
fileInput.after (barContainer);
fileInput.fileupload ({{
fileInput: fileInput,
url: form.data ('url'),
type:'POST',
autoUpload: true,
formData: form.data ('form-data'),
paramName:'file', // S3 does not like nested name fields i.e. name = "user [avatar_url]"
dataType:'XML', // S3 returns XML if success_action_status is set to 201
replaceFileInput: false,
progressall: function (e, data) {
var progress = parseInt (data.loaded/data.total * 100, 10);
progressBar.css ('width', progress +'%')
},
start: function (e) {
submitButton.prop ('disabled', true);
progressBar.
css ('background','green').
css ('display','block').
css ('width', '0%').
text ("Loading ...");
},
done: function (e, data) {
submitButton.prop ('disabled', false);
progressBar.text ("Uploading done");
// extract key and generate URL from response
var key = $(data.jqXHR.responseXML) .find ("Key") .text ();
var url ='//' + form.data ('host') +'/' + key;
// create hidden field
var input = $("<input />", {type:'hidden', name: fileInput.attr ('name'), value: url})
form.append (input);
},
fail: function (e, data) {
submitButton.prop ('disabled', false);
progressBar.
css ("background", "red").
text ("Failed");
}
});});
});</script>
config/initializers/aws.rb
Aws.config.update ({{
region:'ap-northeast-1',
credentials: Aws :: Credentials.new (
'××××××××××××××××××××××××××××××××', # Access key
'××××××××××××××××××××××××××××××××' # Secret Key
),
})
S3_BUCKET = Aws :: S3 :: Resource.new.bucket ('×××××××××××××××××××××') # bucket name
Download the following two libraries and install them under app/assets/javascripts
https://raw.githubusercontent.com/jquery/jquery-ui/master/ui/widget.js
→ app/assets/javascripts/jquery.ui.widget.js
https://raw.githubusercontent.com/blueimp/jQuery-File-Upload/master/js/jquery.fileupload.js
→ app/assets/javascripts/z.jquery.fileupload.js
I implemented it as above, but when I upload the image, the parameters are as follows and it is not uploaded to AWS S3.
Parameters: {"utf8" =>"✓", "authenticity_token" =>"hqGryq1RfJW1tv4XzWOK8xLs3Dazxs3h0u8 + BScjb5N620ynmSg5Xnc5keXHl8QryVY4bolxrMAujB0vdfISTw ==" {">ActionDispatch :: Http :: UploadedFile: 0x00007fa188674298 @tempfile = #<Tempfile:/var/folders/gd/52ml8dfd03v0jfgy6r2ls4x80000gn/T/RackMultipart20201103-12508-1pra42j.jpg>, @ original_filename = "2018-06-29 12.13.jpg. ", @content_type =" image/jpeg ", @ headers =" Content-Disposition: form-data;name = \ "form [user] [avatar] [image] \";filename = \ "2018-06-29 12.13 .08.jpg \ "\ r \ nContent-Type: image/jpeg \ r \ n">},
"name" =>"test01", "email" =>"[email protected]", "profile_text" =>"" "}},
"commit" =>"Update with the above", "id" =>"1"}
↳ app/forms/user_form.rb: 5
User Update (0.2ms) UPDATE "users" SET "profile_text" = $1, "updated_at" = $2 WHERE "users". "Id" = $3 [["profile_text", ""],
["updated_at", "2020-11-03 08: 50: 40.670585"],
["id", 1]]
↳ app/forms/user_form.rb: 5
UserAvatar Create (0.6ms) INSERT INTO "user_avatars" ("user_id", "image", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["user_id", 1] ,
["image", "# "],
["created_at", "2020-11-03 08: 50: 40.671752"],
["updated_at", "2020-11-03 08: 50: 40.671752"]]
↳ app/forms/user_form.rb: 5
(0.5ms) COMMIT
The source code is problematic because the image part contains # I don't think so.
CORS was set as follows from the AWS management screen.
[
{
"AllowedHeaders": [
"*"
],,
"AllowedMethods": [
"GET",
"PUT",
"POST"
],,
"AllowedOrigins": [
"http: // localhost: 3000"
],,
"Expose Headers": [],
"MaxAgeSeconds": 3000
}
]
I would appreciate it if you could tell me the solution. I look forward to working with you.
Reference site: https://qiita.com/DaichiSaito/items/80e89f0c96d88afcc5ff
Reference site: https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails
-
Answer # 1
Related articles
- ruby on rails - s3 images are not saved on the ec2 server
- ruby on rails - i implemented it so that images can be saved in s3 of aws, but the view can no longer be displayed
- ruby on rails - i want to display the posted images in a random order (get information from the record)
- ruby on rails - i want to display all the images in the [rails] directory in the browser!
- ruby - the last db setting doesn't work when deploying rails app on aws
- ruby on rails - i want to avoid displaying duplicate data for each shop
- ruby - i want to display specific columns in rails in descending order of numbers
- [ruby on rails] how to write when getting a model nested in multiple stages with includes
- ruby on rails - when i run rails s, i get
- ruby on rails - i installed ruby with rbenv, but the version does not change
- i want to convert wav to mp3 with ruby on rails and pass it to active strage
- ruby on rails 5 - scope by specifying conditions for parent-child relationship
- ruby on rails 6 - about rails routing error no route matches [get] "/"
- ruby - about implementation of tag function in rails
- ruby on rails - [rails] i'm implementing a search function using form_with, but i'm having trouble with the search results not b
- ruby on rails - i would like to add an automatic address input function to the new registration screen
- ruby - [rails] i want to find the date difference using the model created_at
- ruby on rails - i want to resolve rails wrong number of arguments
- ruby on rails - i want to deploy to aws ec2 server
- ruby - sass :: syntaxerror on rails s
- javascript - i want the scroll bar to always appear at the bottom of the chat screen
- ruby - i want to use two rails renders
- ruby - the top screen is displayed at http: // localhost: 3000/users/sign_in
- ruby - [rails] the class attribute specified by the div tag enclosed in simple_format is not applied
- ruby on rails removal function
- ruby on rails sorting
- html - i can't set the regular expression well
- ruby - rails i want to make the created_at time the same when creating multiple data at once
- ruby - dynamic form implementation in nested_form
It was solved by describing the above.