Rails Carrierwave Uploading to Aws but Not Displaying

Read Time: xi mins Languages:

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

In this article, you will learn how to:

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

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

Laying the Foundations

As always, start by creating a new Rails application:

For this demo I'll be using Rails five.0.two. Please note that Carrierwave 1 supports only Rails four+ and Ruby 2. If yous are notwithstanding riding on Rails 3, so hook up Carrierwave version 0.11.

To see Carrierwave in action, nosotros are going to create a very simple blogging awarding with a sole Post model. It will have the following main attributes:

  • title (cord)
  • body (text)
  • image (string)—this field is going to contain an paradigm (a file's proper name, to exist precise) attached to the post

Generate and utilise a new migration:

Gear up some routes:

config/routes.rb

Too, create a very basic controller:

posts_controller.rb

Now let's arts and crafts the index view:

views/posts/index.html.erb

And the respective partial:

views/posts/_post.html.erb

Here I am using the Railtruncate method to brandish but the showtime 150 symbols from the mail. Earlier nosotros create other views and a form fractional, let's firstly integrate Carrierwave into the application.

Integrating Carrierwave

Drib in a new gem into the Gemfile:

Gemfile

Run:

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

Now, within app/uploaders, you lot will find a new file called image_uploader.rb. Annotation that information technology has some useful comments and examples, so you may use it to get started. In this demo nosotros volition use ActiveRecord, but Carrierwave as well has back up for Mongoid, Sequel, and DataMapper.

Adjacent, 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 now, permit's utilize file storage:

uploaders/image_uploader.rb

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

.gitignore

You may as well modify thestore_dir method inside your uploader to cull some other location.

At this point, we tin can create a new view and a class fractional to start uploading files:

views/posts/new.html.erb

views/posts/_form.html.erb

Note that the PostsController does non need to be modified as nosotros already permitted the epitome attribute.

Lastly, create the edit view:

views/posts/edit.html.erb

That's information technology! You may kick the server and try to create a mail with an image. The problem is that this image is not visible anywhere, so let'due south proceed to the side by side section and add a show page!

Displaying Images

Then, the just view nosotros take non created nonetheless is show. Add it now:

views/posts/show.html.erb

As you tin can encounter, displaying an attachment is really easy: all you need to exercise is say @postal service.prototype.url to catch an paradigm'south URL. To get a path to the file, use thecurrent_path method. Annotation that Carrierwave likewise provides an image? method for us to check whether an attachment is present at all (the prototype method itself will never return nil, even if the file is not present).

Now, after navigating to a post, you should see an epitome, but information technology might appear likewise big: later all, we are not restricting dimensions anywhere. Of course, we could have scaled the image down with some CSS rules, just it is much improve to generate a thumbnail after the file has been uploaded. This, notwithstanding, requires some additional steps.

Generating Thumbnails

In order to crop and calibration images, we need a separate tool. Out of the box Carrierwave has back up for RMagick and MiniMagick gems that, in plough, are used to manipulate images with the help of ImageMagick. ImageMagick is an open-source solution assuasive you to edit existing images and generate new ones, so before proceeding you need to download and install it. Adjacent, you lot are complimentary to pick either of the two gems. I'll stick with MiniMagick, because it is much easier to install and it has ameliorate support:

Gemfile

Run:

Then include MiniMagick into your uploader:

uploaders/image_uploader.rb

Now we simply need to introduce a new version to our uploader. The concept of versions (or styles) is used in many file uploading libraries; it simply means that additional files based on the original attachment volition be created with, for instance, different dimensions or formats. Introduce a new version chosen thumb:

uploaders/image_uploader.rb

Yous may have equally many versions as you like and, what's more, versions can fifty-fifty exist built on tiptop of other ones:

uploaders/image_uploader.rb

If you have already uploaded some images, they won't have thumbnails available. This is not a problem, though, equally you can re-create them from the Rails console:

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

views/posts/show.html.erb

Boot the server and discover the result!

Calculation Validations

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

uploaders/image_uploader.rb

You lot may also add content blazon checks by defining a content_type_whitelist method:

uploaders/image_uploader.rb

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

Autonomously from checking a file'southward type and extension, let'south enforce it to be less than i megabyte. To practise it, we'll require an boosted gem supporting file validations for ActiveModel:

Gemfile

Install it:

Now introduce the desired validations (note that I am also adding checks for the title and body attributes):

models/post.rb

The next thing to do is to add I18n translations for Carrierwave's error messages:

config/locales/en.yml

Currently, we do not display validation errors anywhere, and then let'due south create a shared partial:

views/shared/_errors.html.erb

Utilize this fractional inside the form:

views/posts/_form.html.erb

Now endeavour to upload some invalid files and observe the result. It should work, but if you cull a valid file and practice not fill in the championship or trunk, and then the checks will notwithstanding neglect and an mistake will be displayed. Notwithstanding, the file field will be cleared out and the user will need to choose the prototype again, which is not very user-friendly. To fix it, nosotros demand to add another field to the form.

Persisting Files Across Requests

Persisting files across form redisplays is actually quite easy. All you lot need to do is add together a new subconscious field and allow information technology inside the controller:

views/shared/_form.html.erb

posts_controller.rb

Now the image_cache volition be populated automatically and the image won't exist lost. It may be helpful to display a thumbnail as well so that user understands the image was processed successfully:

views/shared/_form.html.erb

Removing Images

Another very common feature is the ability to remove fastened files when editing a tape. With Carrierwave, implementing this feature is not a problem. Add a new checkbox to the form:

views/shared/_form.html.erb

And permit the remove_image attribute:

posts_controller.rb

That'southward it! To remove an epitome manually, apply 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. Permit'southward introduce this power at present by adding a new field and permitting the corresponding attribute:

views/shared/_form.html.erb

posts_controller.rb

How absurd is that? Y'all don't need to make any changes at all, and you lot can test this feature right away!

Working With Multiple Uploads

Suppose we want our post to take multiple attachments bachelor. With the current setup it is non possible, but luckily, Carrierwave supports such a scenario likewise. To implement this feature, you lot need to add together either a serialized field (for SQLite) or a JSON field (for Postgres or MySQL). I prefer the latter option, so let'due south 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 and then generate and apply the migration:

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

At present mount the uploaders (notation the plural form!):

model/post.rb

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

Add the multiple file field to your form:

views/shared/_form.html.erb

Every bit long as the attachments field is going to incorporate an array, it should exist permitted in the following style:

posts_controller.rb

Lastly, you may iterate over the mail's attachments and display them as usual:

views/shared/prove.html.erb

Note that each zipper is going to have a thumbnail as configured in our ImageUploader. Dainty!

Using Cloud Storage

Sticking with file storage is not always convenient and/or possible as, for instance, on Heroku information technology is not possible to store custom files. Therefore you might inquire how to ally Carrierwave with Amazon S3 cloud storage? Well, that's a pretty easy task as well. Carrierwave depends on the fog-aws gem to implement this characteristic:

Gemfile

Install it:

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

config/initializers/carrierwave.rb

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

I am using the dotenv-rails gem to set up the environment variables in a secure mode, merely yous may choose any other option. However, brand sure that your S3 key pair is not available publicly, because otherwise anyone can upload anything to your saucepan!

Next, replace the storage :file line with:

uploaders/image_uploader.rb

Autonomously from S3, Carrierwave supports uploads to Google Storage and Rackspace. These services are easy to gear up as well.

Conclusion

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

If you are stuck, don't hesitate to post your questions. Also, it might be useful to have a peek into Carrierwave's wiki, which hosts useful "how to" articles answering many common questions.

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

Did you find this post useful?

thompsonabsontrythe42.blogspot.com

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

0 Response to "Rails Carrierwave Uploading to Aws but Not Displaying"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel