Lompat ke konten Lompat ke sidebar Lompat ke footer

How to Upload Pictures Into Ruby Rails Database

Read Time: eleven mins Languages:

This is another article in the "Uploading with Rails" series. Today we are going to meet Carrierwave—one of the near popular file uploading solutions for Rail. I like Carrierwave because it is easy to get started, it has lots of features out of the box, and information technology provides dozens of "how to" articles written by the members of the customs, and so you won't get lost.

In this article, you lot will learn how to:

  • Integrate Carrierwave into your Rails app
  • Add validations
  • Persist files beyond requests
  • Remove files
  • Generate thumbnails
  • Upload files from remote locations
  • Introduce multiple file uploads
  • Add support for deject storage

The source code for this article is available on GitHub. Bask reading!

Laying the Foundations

Equally e'er, start by creating a new Runway application:

For this demo I'll be using Rails 5.0.2. Please note that Carrierwave 1 supports only Rails four+ and Reddish two. If you lot are still riding on Rails three, then hook upwards Carrierwave version 0.11.

To see Carrierwave in action, nosotros are going to create a very simple blogging application with a sole Mail model. It will accept the post-obit master attributes:

  • title (cord)
  • trunk (text)
  • image (string)—this field is going to contain an image (a file'due south name, to be precise) attached to the post

Generate and apply a new migration:

Set some routes:

config/routes.rb

Besides, create a very basic controller:

posts_controller.rb

At present let's craft the index view:

views/posts/index.html.erb

And the corresponding fractional:

views/posts/_post.html.erb

Here I am using the Runwaytruncate method to display only the first 150 symbols from the postal service. Before we create other views and a form partial, let'southward firstly integrate Carrierwave into the application.

Integrating Carrierwave

Driblet in a new gem into the Gemfile:

Gemfile

Run:

Carrierwave stores its configuration insideuploadersthat are included into your models. To generate an uploader, employ the post-obit command:

Now, within app/uploaders, yous will notice a new file called image_uploader.rb. Note that it has some useful comments and examples, then you may use it to get started. In this demo we will use ActiveRecord, merely Carrierwave also has back up for Mongoid, Sequel, and DataMapper.

Next, we need to include or mount this uploader into the model:

models/post.rb

The uploader already has sane default settings, but at the very least nosotros demand to choose where the uploaded files will be stored. For at present, let's employ file storage:

uploaders/image_uploader.rb

By default, files will be placed inside the public/uploads directory, so information technology is best to exclude it from the version control system:

.gitignore

You lot may also modify thestore_dir method inside your uploader to cull some other location.

At this point, we can create a new view and a form fractional to outset uploading files:

views/posts/new.html.erb

views/posts/_form.html.erb

Note that the PostsController does not need to exist modified as nosotros already permitted the image aspect.

Lastly, create the edit view:

views/posts/edit.html.erb

That'due south it! You may boot the server and try to create a post with an image. The trouble is that this epitome is not visible anywhere, so allow's proceed to the next section and add a evidence folio!

Displaying Images

So, the merely view we have not created even so is show. Add it now:

views/posts/show.html.erb

As you can see, displaying an attachment is really easy: all y'all demand to do is say @mail service.image.url to grab an image's URL. To get a path to the file, employ thecurrent_path method. Notation that Carrierwave too provides an image? method for u.s.a. to bank check whether an zipper is nowadays at all (the image method itself will never return nil, even if the file is not present).

Now, afterwards navigating to a mail service, you should see an image, but it might appear likewise large: after all, we are not restricting dimensions anywhere. Of course, we could take scaled the image downwardly with some CSS rules, but it is much meliorate to generate a thumbnail subsequently the file has been uploaded. This, notwithstanding, requires some additional steps.

Generating Thumbnails

In gild to ingather and scale images, we demand a separate tool. Out of the box Carrierwave has support for RMagick and MiniMagick gems that, in plough, are used to manipulate images with the help of ImageMagick. ImageMagick is an open-source solution allowing yous to edit existing images and generate new ones, so before proceeding you need to download and install information technology. Next, you are gratis to choice either of the two gems. I'll stick with MiniMagick, considering it is much easier to install and it has amend back up:

Gemfile

Run:

Then include MiniMagick into your uploader:

uploaders/image_uploader.rb

Now nosotros simply need to innovate a new version to our uploader. The concept of versions (or styles) is used in many file uploading libraries; information technology only means that additional files based on the original zipper will be created with, for example, dissimilar dimensions or formats. Introduce a new version called thumb:

uploaders/image_uploader.rb

You may have as many versions every bit yous like and, what'southward more, versions tin can even be built on top of other ones:

uploaders/image_uploader.rb

If y'all have already uploaded some images, they won't accept thumbnails available. This is non a problem, though, as you tin re-create them from the Rails console:

Lastly, display your thumbnail with a link to the original image:

views/posts/show.html.erb

Boot the server and discover the result!

Adding Validations

Currently our uploading works, only we're non validating user input at all, which is, of course, bad. Equally long every bit we want to piece of work merely with images, let'due south whitelist .png, .jpg and .gif extensions:

uploaders/image_uploader.rb

You may also add content type checks past defining a content_type_whitelist method:

uploaders/image_uploader.rb

Alternatively, it is possible to blacklist some file types, for example executables, by defining thecontent_type_blacklist method.

Apart from checking a file's blazon and extension, let's enforce it to be less than 1 megabyte. To practice information technology, nosotros'll crave an additional gem supporting file validations for ActiveModel:

Gemfile

Install information technology:

Now introduce the desired validations (note that I am as well adding checks for the championship and body attributes):

models/post.rb

The next thing to exercise is to add I18n translations for Carrierwave'south error letters:

config/locales/en.yml

Currently, we practise not display validation errors anywhere, so let's create a shared fractional:

views/shared/_errors.html.erb

Employ this partial within the form:

views/posts/_form.html.erb

Now try to upload some invalid files and observe the upshot. It should work, only if you choose a valid file and do non fill in the championship or body, so the checks volition still neglect and an fault volition exist displayed. Notwithstanding, the file field volition be cleared out and the user volition need to choose the image again, which is not very convenient. To ready information technology, we demand to add together another field to the form.

Persisting Files Across Requests

Persisting files across form redisplays is actually quite easy. All you need to do is add a new hidden field and permit it inside the controller:

views/shared/_form.html.erb

posts_controller.rb

Now the image_cache will be populated automatically and the image won't be lost. It may exist helpful to brandish a thumbnail every bit well and then that user understands the prototype was processed successfully:

views/shared/_form.html.erb

Removing Images

Some other very common feature is the ability to remove attached files when editing a record. With Carrierwave, implementing this characteristic is not a problem. Add a new checkbox to the form:

views/shared/_form.html.erb

And allow the remove_image attribute:

posts_controller.rb

That's it! To remove an image manually, use theremove_image! method:

Uploading From a Remote Location

Carrierwave also provides a very cool feature out of the box: the ability to upload files from remote locations by their URL. Let's introduce this ability now by adding a new field and permitting the respective attribute:

views/shared/_form.html.erb

posts_controller.rb

How cool is that? You don't demand to brand any changes at all, and y'all can examination this characteristic right abroad!

Working With Multiple Uploads

Suppose we want our mail service to have multiple attachments available. With the current setup information technology is not possible, but luckily, Carrierwave supports such a scenario besides. To implement this characteristic, you demand to add either a serialized field (for SQLite) or a JSON field (for Postgres or MySQL). I adopt the latter pick, so allow's switch to a new database adapter now. Remove the sqlite3 gem from the Gemfile and add pg instead:

Gemfile

Install it:

Modify the database configuration like this:

config/database.yml

Create the corresponding Postgres database, and so generate and apply the migration:

If you prefer to stick with SQLite, follow the instructions listed in Carrierwave'south documentation.

Now mount the uploaders (note the plural class!):

model/post.rb

I am using the same uploader for attachments, but of course y'all tin generate a new i with a different configuration.

Add the multiple file field to your form:

views/shared/_form.html.erb

Every bit long every bit the attachments field is going to contain an assortment, it should be permitted in the following mode:

posts_controller.rb

Lastly, yous may iterate over the mail service'due south attachments and display them as usual:

views/shared/show.html.erb

Note that each zipper is going to have a thumbnail every bit configured in our ImageUploader. Nice!

Using Cloud Storage

Sticking with file storage is not always user-friendly and/or possible every bit, for example, on Heroku it is not possible to store custom files. Therefore you might inquire how to marry Carrierwave with Amazon S3 cloud storage? Well, that's a pretty easy task every bit well. Carrierwave depends on the fog-aws precious stone to implement this feature:

Gemfile

Install it:

Permit's create an initializer for Carrierwave and configure the deject storage globally:

config/initializers/carrierwave.rb

There are another options available, which can be found in the documentation.

I am using the dotenv-rails precious stone to gear up the surroundings variables in a secure way, but you may choose any other option. Nonetheless, make certain that your S3 key pair is not bachelor publicly, because otherwise anyone tin can upload anything to your bucket!

Next, replace the storage :file line with:

uploaders/image_uploader.rb

Apart from S3, Carrierwave supports uploads to Google Storage and Rackspace. These services are easy to set upward every bit well.

Conclusion

This is information technology for today! We have covered all the major features of Carrierwave, and now you can start using it in your projects. It has some additional options available, so do browse the documentation.

If you are stuck, don't hesitate to mail your questions. Too, information technology might be useful to accept a peek into Carrierwave's wiki, which hosts useful "how to" articles answering many mutual questions.

And so I thank you for staying with me, and happy coding!

Did you notice this mail service useful?

mcclainstroardlean.blogspot.com

Source: https://code.tutsplus.com/articles/uploading-with-rails-and-carrierwave--cms-28409

Posting Komentar untuk "How to Upload Pictures Into Ruby Rails Database"