Example of upload and display of ruby on rails climbing pit picture

Source: Internet
Author: User
Tags ruby on rails

One, problems and ideas

Recently in the rails + react + MySQL basic framework to write a CMS + client project, which involves the image upload and display, the following simple ideas, as for the deployment of the project, should be in the end of the winter break to share.

The main problem with uploading and displaying pictures in rails is:

Where does the picture exist?
Picture format size?
How does the client display the picture?
Because it's a small project, estimate up to 1000 pictures, up to 1G of space, so take a relatively simple approach: The picture is saved in the Rails public folder (that is, in the host where the project is deployed), and if the picture is more, it is recommended to use the services provided by Amazon Cloud S3 (understood as a hard drive, S3 provides an interface for you to access things, secure, and manage conveniently).

The general idea is that the front end through the <input type= "file"/> Select files, send AJAX requests to the back-end of the Controller,controller the requested picture data to size, type conversion after saving to the local designated folder, Returns the path at the same time to display the picture.

Second, the practice

The idea is relatively simple, so the words do not say more directly on the code:

The front-end code is integrated in a picture upload component written by react, and the IMAGE_UPLOADER.JS.JSX code is as follows

var Imageuploader = React.createclass ({
Getinitialstate:function () {
return {
Url:this.props.url
};
},
Onfileselect:function (e) {
var that = this;
var files = e.target.files;
if (files.length <= 0) {
Alertmodal.showwithprops ("No file selected");
Return
}
var data = new FormData ();
$.each (Files, function (key, value) {
Data.append (' file ', value);
Data.append (' type ', That.props.type)
});
This.upload (data);
},
Upload:function (data) {
var that = this;
if (!data) {
Return
} else {
This.refs.filebtn.disabled = true;
$ ("#loading-modal"). Modal (' show ');
$.ajax ({
URL: '/missions/upload_image ',
Type: ' Post ',
Data:data,
Processdata:false,
Contenttype:false
). Done (function (res) {
Console.log (RES);
That.setstate ({url:res.url});
}). Fail (function (ERR) {
Console.log (ERR);
Alertmodal.showwithprops ("Upload Failed");
}). Always (function () {
$ ("#loading-modal"). Modal (' hide ');
that.refs.filebtn.disabled = false;
});
}
},
Handleurlchange:function (e) {
This.setstate ({url:e.target.value});
},
Render:function () {
var form_input_name = This.props.model + "[Thumb]";
var form_input_id = this.props.model+ "_thumb";
Return (
<div classname= "Image-uploader-inputs row" >
<div classname= "Col-sm-8 image-input" >
<input classname= "Form-control" Name={form_input_name} id={form_input_id} ref= "Urlinput" Value={this.state.url | | ""} onchange={this.handleurlchange}/>
</div>
<div classname= "btn btn-primary btn-file image-input-btn" >
<input type= "File" Onchange={this.onfileselect} ref= "Filebtn"/>
</div>
</div>
);
}
});

The above focus on the upload function, the source code is the best document, if you want to see the source code needs too many comments, it must be I write the quality of the coding is not high enough, please criticize.

Two questions were encountered when writing this:

One, this component is used in the _form.html.slim, this form is used for the input of the information, we should be more familiar with the form, since to use in the form, that is to identify the component, indicate the name and ID, the code fragment as follows (from the above code interception):
var form_input_name = This.props.model + "[Thumb]";
var form_input_id = this.props.model+ "_thumb";
<input classname= "Form-control" Name={form_input_name} id={form_input_id} ref= "Urlinput" Value={this.state.url | | ""} onchange={this.handleurlchange}/>
Second, the use of <input type= "file"/> has a common problem with the UI is not beautiful.


Google/Baidu "input file btn" There will be many solutions, home network speed is not close. My approach is to set this btn to be transparent, the relevant code and CSS as follows:

<div classname= "btn btn-primary btn-file image-input-btn"
  <input type= "file" onchange={ This.onfileselect} ref= "Filebtn"/>
</div>
. image-input-btn {
    float:left;
    width:15%;
    background-image:image-url ("Upload.png");
    background-size:30px;
    Background-position:center;
    background-repeat:no-repeat;
    Input {
     //hide file input button
       Width:inherit;
      opacity:0;
   }
 }
Ten
One


Take a look at the back-end code:

def upload_image
# => 'll resize later
Image_relative_path = "/assets/images/#{params[:type]}/#{time.now.to_i}.png"
Image_path = File.expand_path (File.dirname (__file__) + '/. /..') + "/public" + Image_relative_path

data = File.read (Params[:file].path)
img = file.new (image_path, "w+")
If img
Img.syswrite (data)
End
Img.close
Render json: {Url:image_relative_path}
End
10
11
12
13
The code is just as simple, building the file path, saving the file, and returning the path. Because the development progress reason here does not have the picture size and the type to make the revision (in order to reduce the data transmission quantity, in the front the size modification is more reasonable), later review this part of code will update this blog again.

It is worth saying that:

Picture naming problem, the use of timestamp, the name will not repeat, in order to facilitate management, the different types of pictures in different folders, but only the time stamp to name the available information is too small, not conducive to the management of operators, later will carefully consider this issue.
A problem with the path, in the back-end code, rails can place the picture anywhere in the Rails project folder, but when the client displays the picture, it can only access the contents of the public folder, and then decides to have the picture under the public folder.
Third, summing up and thinking

It doesn't take long to complete this function, but there's a lot of thinking outside the code. Small picture, even can use Git to back up the picture, perhaps not long-term, began to miss AWS good, disaster-tolerant to AWS processing best, and then interviewed a bit AWS S3

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.