Web Services: Outgoing with JSON, XML, & CSV

Free Ruby on Rails Tutorial

Discover how to seamlessly syndicate your data to a partner site with this detailed Ruby on Rails tutorial, covering critical topics like converting product info into JSON, creating an XML file, and using Active Admin to export CSV.

This exercise is excerpted from Noble Desktop’s past web development training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Topics covered in this Ruby on Rails tutorial:

Converting product info into JSON, Creating an XML file, Using Active Admin to export CSV

Exercise Overview

In this exercise, we’ll learn how we can syndicate our data out to a partner.

  1. If you completed the previous exercises, you can skip the following sidebar. We recommend you finish the previous exercises (8A–11B) before starting this one. If you haven’t finished them, do the following sidebar.

    If You Did Not Do the Previous Exercises (8A–11B)

    1. Close any files you may have open.
    2. Open the Finder and navigate to Class Files > yourname-Rails Class
    3. Open Terminal.
    4. Type cd and a single space (do NOT press Return yet).
    5. Drag the yourname-Rails Class folder from the Finder to the Terminal window and press ENTER.
    6. Run rm -rf nutty to delete your copy of the nutty site.
    7. Run git clone https://bitbucket.org/noble-desktop/nutty.git to copy the That Nutty Guy git repository.
    8. Type cd nutty to enter the new directory.
    9. Type git checkout 11B to bring the site up to the end of the previous exercise.
    10. Run bundle to install any necessary gems.
    11. Run yarn install --check-files to install JavaScript dependencies.

Converting Product Info into a JSON feed

Let’s say that hypothetically, we’ve struck a deal with a comedy blog that’s going to feature our products on their website. We don’t want to make them add all our product info manually, nor would we want them to show out-of-date info if data on our site changes. We’ve seen how easy it is to receive data as JSON onto our site; let’s share our products as JSON with another site.

Full-Stack Web Development Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.
  1. For this exercise we’ll continue working with the nutty folder located in Desktop > Class Files > yourname-Rails Class > nutty

    If you haven’t already done so, we suggest opening the nutty folder in your code editor if it allows you to (like Sublime Text does).

  2. You should still have a window with two tabs open in Terminal from the last exercise, the first of which is running the server. If you don’t, complete the following sidebar.

    Restarting the Rails Server

    1. In Terminal, cd into the nutty folder:
    • Type cd and a space.
    • Drag the nutty folder from Desktop > Class Files > yourname-Rails Class onto the Terminal window (so it will type out the path for you).
    • In Terminal, hit Return to change directory.
    1. In Terminal, type the following:

      rails s
      
    2. Open a new tab (Cmd–T) leaving our server running in the old tab.
    3. In the new tab, cd into the nutty folder:
    • Type cd and a space.
    • Drag the nutty folder from Desktop > Class Files > yourname-Rails Class onto the Terminal window (so it will type out the path for you).
    • In Terminal, hit Return to change directory.
  3. In your code editor, open nutty > app > controllers > products_controller.rb

    We want to be able to render all of the products on our site as JSON. In order to do that, we can use the existing index action for products.

  4. Starting around line 7, add the following bold code:

    def index
       @get_nutty = true
       @products = Product.all
       respond_to do |format|
          format.html
          format.json { render json: @products }
       end
    end
    

    NOTE: This is where we use the respond_to helper that you might recall from scaffolding exercise earlier. Basically, any controller action can respond to different formats of a request and render its output in different ways.

  5. Save the file and leave it open.

  6. In the browser go to our products page at: localhost:3000/products

  7. In the browser go to: localhost:3000/products.json

    Now you should see a JSON feed with all our product info we saw in the previous step. We can access this the same way as anything else from the Rails console.

  8. In Terminal, type the following to start the Rails console:

    rails c
    
  9. In Terminal, type the following to return a nice, long JSON response:

    r = HTTParty.get('http://localhost:3000/products.json')
    
  10. We can do all the same things here as with the bitpay.com API, so try typing:

    r.count
    r.first['title']
    

    You should get back the number of objects (8) and the title of the first object (Tinfoil Hat).

    If our partner site is fortunate enough to be using Ruby on Rails, they’ll have an easy time working with our data. However, there are a few reservations we have about this. For one, we’re exposing all the data about every product. There’s nothing super-secret here at the moment, but what if we added sensitive values like cost or MAP price in the future?

  11. Fortunately, we can specify which properties are displayed. Go back to products_controller.rb in your code editor.

  12. Add the following bold code around line 9:

    format.json { render json: @products, only: [:title, :sku, :price] }
    
  13. Save the file and leave it open.

  14. In the browser reload: localhost:3000/products.json

    Now it should list just the title, SKU, and price of each product. So much cleaner!

Adding a Model Method

Let’s give our partner a simple link to promote each product.

  1. In your code editor, open nutty > app > models > product.rb

  2. Around line 15, create a method to send the path to the image:

       friendly_id :title, use: [:slugged, :finders]
    
       def partner_link
          "https://www.thatnuttyguy.com/products/#{slug}"
       end
    end
    
  3. Save the file and close it.

  4. In your code editor, open nutty > app > controllers > products_controller.rb

  5. Add the bold code around line 9 (don’t miss the comma):

    format.json { render json: @products, only: [:title, :sku, :price], methods: [:partner_link] }
    
  6. Save the file.

  7. In the browser reload: localhost:3000/products.json

    Great, now the full URLs for the products are included.

Creating an XML File

Now, let’s say our partner site just told us their CMS (content management system) can’t parse JSON at all and have requested XML instead. Rails makes this easy!

  1. Switch back to your code editor and the products_controller.rb file.

  2. Copy the line of code for JSON (around line 9) and paste a copy directly underneath, editing the new line by simply replacing json with xml as shown:

    format.json { render json: @products, only: [:title, :sku, :price], methods: [:partner_link] }
    format.xml { render xml: @products.as_json(only: [:title, :sku, :price], methods: [:partner_link]) }
    
  3. Save the file.

  4. In the browser, navigate to: localhost:3000/products.xml

    We have an XML file! (Yes, we are cheating a little bit by rendering the product to JSON first, and then rendering the JSON as XML.) This is the kind of thing Rails excels at: sharing data between sites and being interactive. In other programming languages, getting these results might take much more work.

CSV Exports

Now the accounting department is requesting a CSV export for orders. Fortunately, Active Admin offers some great CSV export tools. First, we need to add orders as a resource to Active Admin.

  1. In Terminal, quit the Rails console, then generate a new resource:

    exit
    rails g active_admin:resource order
    
  2. To check if this worked, we need to place an order. In the browser, navigate to: localhost:3000

  3. Add a couple products to your cart (unless it already has products in it).

  4. Go to the Cart page if you’re not already there, and click Checkout.

  5. Navigate to: localhost:3000/admin

  6. Sign in if prompted. If you do not have an account or started from a prepared folder, complete the following sidebar to log in.

    Creating a Login

    1. Log in with the following:

      Email: admin@example.com
      Password: password
    2. At the top of the Dashboard, in the gray bar, click Admin Users.

    3. To the far right of admin@example.com (the only user), click Edit.

    4. Set the following:

      Email: your email address (Use an account you can access in class!)
      Password: student1
    5. Click the Update Admin user button.

    6. Log in again with your new info.
  7. If you have trouble logging in, try the following workaround:

    Creating User Info in Terminal

    1. In Terminal, open a new tab Ctrl–C
    2. Enter the console by typing rails c
    3. Type the following to create an admin username and password (all on one line in Terminal):

      AdminUser.create :email => 'admin@example.com', :password => 'password', :password_confirmation => 'password'
      
    4. In the browser return to http://localhost:3000/admin. You should be able to log in.
    5. Complete steps 2–6 from the sidebar above.

  8. At the top, click the Orders link.

  9. Below the order, notice there are Download links to CSV, XML, and JSON provided by default.

  10. Click the CSV link.

  11. If it doesn’t automatically open in the browser, go into your computer’s Downloads folder and open it in Excel if you have it.

    It’s a decent start, but we would really like more info here. We could improve this by editing the index page (and we already know how to do that), but what if we want our order export to be different than the index page?

  12. In your code editor, open nutty > app > admin > order.rb

  13. Delete the commented out code.

  14. Add the code shown in bold:

    ActiveAdmin.register Order do
       csv do
          column :id
          column :email
          column :total
          column("Products") { |o| o.products.collect(&:title).join(", ") }
          column("Order Date") { |o| o.created_at.strftime("%-m/%-d/%Y %-I:%M%p") }
       end
    end
    

    NOTE: By default, the time was displayed in military time, but we’d rather customize it to show the month/day/year and hour/minute/am or pm.

  15. Save the file.

  16. In the browser, reload: localhost:3000/admin/orders.csv
    (or reload the Orders page and click the CSV download link.)

    Now we have our custom order info ready for export!

  17. Leave Terminal, your code editor, and browser open as we will continue to work with them in the following exercise.

Noble Desktop Publishing Team

The Noble Desktop Publishing Team includes writers, editors, instructors, and industry experts who collaborate to publish up-to-date content on today's top skills and software. From career guides to software tutorials to introductory video courses, Noble aims to produce relevant learning resources for people interested in coding, design, data, marketing, and other in-demand professions.

More articles by Noble Desktop Publishing Team

How to Learn Coding

Master coding with hands-on training. Learning how to code in JavaScript, Python, and other popular languages can pave the way to a job in tech, such as web development, data science & analytics, or software engineering.

Yelp Facebook LinkedIn YouTube Twitter Instagram