edit-icon download-icon

Integration with Rails

Last Updated: Nov 06, 2017

To use the OSS Ruby SDK in Rails, add the following dependency to Gemfile:

  1. gem 'aliyun-sdk', '~> 0.3.0

Then introduce the dependency when you use OSS:

  1. require 'aliyun/oss'

The “rails/“ directory of the SDK provides helper code to facilitate your operation.

The following describes how to use the SDK to implement a simple OSS object manager (oss-manager) which provides the following functionality:

  • List all the buckets of a user.
  • List all the objects in a bucket by level of directory.
  • Upload objects.
  • Download objects.

1. Create a project

Install Rails and create a Rails application oss-manager:

  1. gem install rails
  2. rails new oss-manager

We recommend, you manage your project code in GitHub:

  1. cd oss-manager
  2. git init
  3. git add .
  4. git commit -m "init project"

2. Add the SDK dependency

Add the SDK dependency to oss-manager/Gemfile:

  1. gem 'aliyun-sdk', '~> 0.3.0'

Run the following command in oss-manager/:

  1. bundle install

Save the change in this step:

  1. git add .
  2. git commit -m "add aliyun-sdk dependency"

3. Initialize an OSSClient

To avoid initializing an OSSClient instance each time you use it in the project, you can add an initialization file to your project.

  1. # oss-manager/config/initializers/aliyun_oss_init.rb
  2. require 'aliyun/oss'
  3. module OSS
  4. def self.client
  5. unless @client
  6. Aliyun::Common::Logging.set_log_file('./log/oss_sdk.log')
  7. @client = Aliyun::OSS::Client.new(
  8. endpoint:
  9. Rails.application.secrets.aliyun_oss['endpoint'],
  10. access_key_id:
  11. Rails.application.secrets.aliyun_oss['access_key_id'],
  12. access_key_secret:
  13. Rails.application.secrets.aliyun_oss['access_key_secret']
  14. )
  15. end
  16. @client
  17. end
  18. end

The preceding code can be found in the “rails/“ directory of the SDK. The initialization file simplifies the use of the OSSClient in your project:

  1. buckets = OSS.client.list_buckets

The endpoint, AccessKeyID, and AccessKeySecret are stored inoss-manager/conf/secrets.yml. For example:

  1. development:
  2. secret_key_base: xxxx
  3. aliyun_oss:
  4. endpoint: xxxx
  5. access_key_id: aaaa
  6. access_key_secret: bbbb

Save the code:

  1. git add .
  2. git commit -m "add aliyun-sdk initializer"

4. Implement the “List Buckets” feature

Firstly, use Rails to generate a controller for bucket management:

  1. rails g controller buckets index

The following objects are generated in oss-manager:

  • app/controller/buckets_controller.rb: The bucket-related logic code
  • app/views/buckets/index.html.erb: The bucket-related demonstration code
  • app/helpers/buckets_helper.rb: Some helper functions

Edit buckets_controller.rb. Call the OSSClient to save the list_buckets results to the @buckets variable:

  1. class BucketsController < ApplicationController
  2. def index
  3. @buckets = OSS.client.list_buckets
  4. end
  5. end
  6. Edit views/buckets/index.html.erb to display the bucket list:
  7. ```html
  8. <h1>Buckets</h1>
  9. <table class="table table-striped">
  10. <tr>
  11. <th>Name</th>
  12. <th>Location</th>
  13. <th>CreationTime</th>
  14. </tr>
  15. <% @buckets.each do |bucket| %>
  16. <tr>
  17. <td><%= link_to bucket.name, bucket_objects_path(bucket.name) %></td>
  18. <td><%= bucket.location %></td>
  19. <td><%= bucket.creation_time.localtime.to_s %></td>
  20. </tr>
  21. <% end %>
  22. </table>

The bucket_objects_path is a helper function is stored inapp/helpers/buckets_helper.rb:

  1. module BucketsHelper
  2. def bucket_objects_path(bucket_name)
  3. "/buckets/#{bucket_name}/objects"
  4. end
  5. end

This is how all the buckets are listed. Before you implement the function, configure a Rails route so that the correct logic can be called after an address is entered in the address bar of the browser. Edit config/routes.rb and add the following:

  1. resources :buckets do
  2. resources :objects
  3. end

Now, input rails s in oss-manager/ to start the Rails server, and input http://localhost:3000/buckets/ in the address bar of the browser. The bucket list is displayed.

Finally, save the code.

  1. git add .
  2. git commit -m "add list buckets feature"

5. Implement the “List Objects” feature

First generate a controller for object management:

  1. rails g controller objects index

Edit app/controllers/objects_controller.rb as follows:

  1. class ObjectsController < ApplicationController
  2. def index
  3. @bucket_name = params[:bucket_id]
  4. @prefix = params[:prefix]
  5. @bucket = OSS.client.get_bucket(@bucket_name)
  6. @objects = @bucket.list_objects(:prefix => @prefix, :delimiter => '/')
  7. end
  8. end

The preceding code obtains the bucket name from the URL parameters first. An additional prefix is required to list objects by directory level. Call the list_objects interface of the OSSClient to obtain the object list. Note that the preceding procedure provide a list of the objects which are delimited by the slash (/) and whose names contain a specified prefix. This also aims to display the object list by directory level. See Manage objects.

Next, edit app/views/objects/index.html.erb as follows:

  1. <h1>Objects in <%= @bucket_name %></h1>
  2. <p> <%= link_to 'Upload file', new_object_path(@bucket_name, @prefix) %></p>
  3. <table class="table table-striped">
  4. <tr>
  5. <th>Key</th>
  6. <th>Type</th>
  7. <th>Size</th>
  8. <th>LastModified</th>
  9. </tr>
  10. <tr>
  11. <td><%= link_to '../', with_prefix(upper_dir(@prefix)) %></td>
  12. <td>Directory</td>
  13. <td>N/A</td>
  14. <td>N/A</td>
  15. </tr>
  16. <% @objects.each do |object| %>
  17. <tr>
  18. <% if object.is_a?(Aliyun::OSS::Object) %>
  19. <td><%= link_to remove_prefix(object.key, @prefix),
  20. @bucket.object_url(object.key) %></td>
  21. <td><%= object.type %></td>
  22. <td><%= number_to_human_size(object.size) %></td>
  23. <td><%= object.last_modified.localtime.to_s %></td>
  24. <% else %>
  25. <td><%= link_to remove_prefix(object, @prefix), with_prefix(object) %></td>
  26. <td>Directory</td>
  27. <td>N/A</td>
  28. <td>N/A</td>
  29. <% end %>
  30. </tr>
  31. <% end %>
  32. </table>

In the preceding code, the main logic for listing objects according to the directory structure is as follows:

  1. “../“ always appears at the beginning to indicate the upper-level directory.
  2. Objects with a common prefix in their names are displayed as directories.
  3. Objects are displayed as files.

The preceding code uses with_prefix, remove_prefix, and other helper functions which are defined in app/helpers/objects_helper.rb:

  1. module ObjectsHelper
  2. def with_prefix(prefix)
  3. "?prefix=#{prefix}"
  4. end
  5. def remove_prefix(key, prefix)
  6. key.sub(/^#{prefix}/, '')
  7. end
  8. def upper_dir(dir)
  9. dir.sub(/[^\/]+\/$/, '') if dir
  10. end
  11. def new_object_path(bucket_name, prefix = nil)
  12. "/buckets/#{bucket_name}/objects/new/#{with_prefix(prefix)}"
  13. end
  14. def objects_path(bucket_name, prefix = nil)
  15. "/buckets/#{bucket_name}/objects/#{with_prefix(prefix)}"
  16. end
  17. end

Once you run the preceding code, run rails s, and enter http://localhost:3000/buckets/my-bucket/objects/ in the address bar of the browser. The object list is displayed.

Save the code as usual:

  1. git add .
  2. git commit -m "add list objects feature"

6. Download objects

Note: The preceding code adds a link to each listed object:

  1. <td><%= link_to remove_prefix(object.key, @prefix),
  2. @bucket.object_url(object.key) %></td>

The Bucket#object_url method is used to generate a temporary URL for an object. For more information, see Download objects.

7. Upload files

You can use either of the following methods to upload files with a server app such as Rails:

  • Upload a file to the Rails server that uploads the object to the OSS. In this method, the Rails server works as a transit server by copying the object to the OSS. The upload process is inefficient.

  • Upload a file to the OSS directly with the form and temporary credentials generated by the Rails server.

The first method is relatively simple, similar to the common file upload method. The following describes how to use the second method to upload a file:

Add a #new method to app/controllers/objects_controller.rb to generate an upload form.

  1. def new
  2. @bucket_name = params[:bucket_id]
  3. @prefix = params[:prefix]
  4. @bucket = OSS.client.get_bucket(@bucket_name)
  5. @options = {
  6. :prefix => @prefix,
  7. :redirect => 'http://localhost:3000/buckets/'
  8. }
  9. end

Then edit app/views/objects/new.html.erb as follows:

  1. <h2>Upload object</h2>
  2. <%= upload_form(@bucket, @options) do %>
  3. <table class="table table-striped">
  4. <tr>
  5. <td><label>Bucket:</label></td>
  6. <td><%= @bucket.name %></td>
  7. </tr>
  8. <tr>
  9. <td><label>Prefix:</label></td>
  10. <td><%= @prefix %></td>
  11. </tr>
  12. <tr>
  13. <td><label>Select file:</label></td>
  14. <td><input type="file" name="file" style="display:inline" /></td>
  15. </tr>
  16. <tr>
  17. <td colspan="2">
  18. <input type="submit" class="btn btn-default" value="Upload" />
  19. <span>&nbsp;&nbsp</span>
  20. <%= link_to 'Back', objects_path(@bucket_name, @prefix) %>
  21. </td>
  22. </tr>
  23. </table>
  24. <% end %>

Specifically, the upload_form is a helper function provided by SDK to generate an upload form. The function is stored in rails/aliyun_oss_helper.rb of the SDK. You must copy the function to theapp/helpers/ directory, run rails s, and input the http://localhost:3000/buckets/my-bucket/objects/new in the address bar of the browser. The file is uploaded.

Do not forget to save the code:

  1. git add .
  2. git commit -m "add upload object feature"

8. Add a style

You can add some styles (CSS) to refine the page outlook.

Download bootstrap. Unzip the package and then copy bootstrap.min.css to app/assets/stylesheets/.

Open app/views/layouts/application.html.erb and modify the yield line as follows:

  1. <div id="main">
  2. <%= yield %>
  3. </div>

In this way, each page is added with a <div> with main as the ID. Then modify app/assets/stylesheets/application.css and add the following content:

  1. body {
  2. text-align: center;
  3. }
  4. div#main {
  5. text-align: left;
  6. width: 1024px;
  7. margin: 0 auto;
  8. }

The preceding modification displays the body content of a webpage in a centered layout. The new style makes the page layout more elegant.

So far, a simple demo has been completed. For a complete demo, see Alibaba Cloud OSS Rails Demo.

Thank you! We've received your feedback.