Ask A Question

Notifications

You’re not receiving notifications from this thread.

HTTParty and trycelery.com API

Edward Bishop asked in General

Ok. I have tried for 3 days and I'm not getting anywhere.

I am building a small kickstarter style campaign module for several products that will be run through Celery. What I want to accomplish is the following:

  1. Retrieve a list of products (id and name) to be served in a dropdown when I build a new campaign.
  2. Retrieve the total number of orders for a specific product based on its id

Celery seems to allow all of the above (https://github.com/airbrite/celery-api/blob/master/README.md) but I am stuck trying to parse the GET response from the API.

I have a Campaigns controller:

class CampaignsController < ApplicationController
  def new
    @campaign = Campaign.new

   @response = HTTParty.get("https://api.trycelery.com/v2/products.json?limit=1&access_token=my_access_token")
   @http_party_json = JSON.parse(@response.body)
 end

def create
  @campaign = Campaign.new(campaign_params)

  if @campaign.save
    redirect_to @campaign
  else
    render 'new'
  end
  end

  private

  def campaign_params
  params.require(:campaign).permit(:campaign_name, :product_id, :campaign_goal, :expiration_date, :ship_date)
  end

end

In my new.html.erb for Campaigns:

<p>New Campaign</p>
<ul>
  <% @http_party_json.each do | event | %>
    <% event.each do | e | %>
      <li><%= e %></li>
    <% end %>
  <% end %>
</ul>

<%= render 'form' %>

Which renders the following JSON response:

meta
{"code"=>200, "paging"=>{"total"=>8, "count"=>1, "limit"=>1, "offset"=>0, "page"=>1, "pages"=>8, "has_more"=>true}}
data
[{"_id"=>"5558cc89695f1d0a00c135d8", "slug"=>"c5251d8b-38ce-42be-918a-9809b2cf57dc", "name"=>"B3/B4 Gauge Face Kit", "description"=>"<p>A replacement gauge face kit for your Audi B3/B4. With a design inspired from the new 2014 Audi RS models, this kit will surely spruce up your interior.</p><p><span style=\"line-height: 1.42857143;\"><br>For B3/B4's with:</span><br></p><p>160MPH top speed</p><p>With or without secondary KPH speedometer</p><p>H/C Temperature gauge</p>", "sku"=>nil, "price"=>0, "weight"=>0, "inventory"=>0, "published"=>true, "flags"=>{"enable_taxes"=>false, "enable_options"=>true, "enable_inventory"=>false}, "images"=>[{"url"=>"https://www.filepicker.io/api/file/AweGJ4LeQfCS11iv2bjr"}], "options"=>[{"id"=>"affbfcae-94e9-4d60-904f-f70509eea028", "values"=>[{"id"=>"baeb4c3f-4718-42d2-8636-0846305756af", "name"=>"160MPH"}], "name"=>"Speedometer Top Speed"}, {"id"=>"09324b68-6974-4f2a-83fb-f587a32f138a", "values"=>[{"id"=>"2d45302d-a5ad-4036-be0a-ecba1bc40312", "name"=>"None"}, {"id"=>"9ee96fd2-9b23-4c3d-932a-3457c523931e", "name"=>"260KPH"}], "name"=>"Secondary Speedometer"}], "variants"=>[{"id"=>"3755bbe3-b6fe-4a07-9d3b-57e704e4a81b", "options"=>{"ids"=>["baeb4c3f-4718-42d2-8636-0846305756af", "2d45302d-a5ad-4036-be0a-ecba1bc40312"], "names"=>["Speedometer Top Speed", "Secondary Speedometer"], "values"=>["160MPH", "None"]}, "price"=>7900, "weight"=>0, "name"=>"160MPH-None"}, {"id"=>"bf1f792f-630b-4254-b0f1-4ef467966a50", "options"=>{"ids"=>["baeb4c3f-4718-42d2-8636-0846305756af", "9ee96fd2-9b23-4c3d-932a-3457c523931e"], "names"=>["Speedometer Top Speed", "Secondary Speedometer"], "values"=>["160MPH", "260KPH"]}, "price"=>7900, "weight"=>0, "name"=>"160MPH-260KPH"}], "user_id"=>"52204519512d70040000000a", "version"=>"v2", "created"=>1431882889328, "updated"=>1431884697130, "created_date"=>"2015-05-17T17:14:49.328Z", "updated_date"=>"2015-05-17T17:14:49.328Z", "locked"=>false, "metadata"=>{}}]

followed by my form partial.

I'm after the "_id" and the "name" objects. Whats interesting is that the loop returns four

  • elements

    1. meta
    2. {"code"...}
    3. data
    4. [{"_id"...]

    Objective 1
    How can I target the 4th blob and parse that to obtain an array of just _id's and names?
    I want create that array so I can use it in my f.select so that it shows me the names but enters the _id in the database

    Objective 2
    I am trying to use the API to obtain a total number of unpaid orders related to a specific product _id.
    I am trying the following but not quite sure if it will succeed.

    StaticPagesController

    orders = HTTParty.get "https://api.trycelery.com/v2/orders?payment_status=unpaid&line_items.product_id={_id}&access_token=my_access_token"
    @order_count = orders["total"].to_i
    @percent_complete = 100.0 * @order_count / 50
    

    I'm just testing on a single product but will be running 4 simulateneous campaigns so I will need to make this code more dynamic and loop through the products to obtain the @order_counts for each product.

    Any help would be fantastic as its quite difficult to wrap my head around this being super new to RoR.

  • Reply

    Hey Edwards,

    For Objective 1, I think you'll want to do something like this:

    @ids_and_names = @http_party_json["data"].map{ |item| [item["id"], item["name"] }
    

    When you parse as JSON, you get a regular old Ruby hash and you can select out the items you want (the ones in "data") and then transform them with map into an array of ids and names. You might need to change the order so it's Name first and then ID in the arrays, can't quite remember.

    For Objective 2, I think that should do it for you and changing the product_id would give you the right results. You'll want to probably change @percent_complete = 100.0 * @order_count / 50 to be calculation with the goal amount as a variable instead of the number 50 unless it is always 50 you are shooting for.

    Reply

    Brilliant Chris! It helps to have a direct example to understand the documentation.

    Reply
    Join the discussion
    Create an account Log in

    Want to stay up-to-date with Ruby on Rails?

    Join 82,329+ developers who get early access to new tutorials, screencasts, articles, and more.

      We care about the protection of your data. Read our Privacy Policy.