1

I currently store a series of tweets as documents in mongodb the schema of which directly map to the json returned by the streaming API.

The schema is very verbose with many nested embedded documents e.g.

{
  "_id": ObjectId("4f547c17e948fb6e2e00197d"),
  "key: value",
  "...",
  "...",
  "entities": {
    "urls": [
       {
        "indices": [
          58,
          78
        ],
        "display_url": "bit.ly\/yJwQsm",
        "url": "http:\/\/t.co\/x5ccL6So",
        "expanded_url": "http:\/\/bit.ly\/yJwQsm"
      }
    ],
  }
  "other parent key pair values here" 
}

Sometimes the urls embed will be empty while other times it will contain more than one value (in a further array like nesting [0], [1] [n])

I'd like to extract the link values from this json document.

I have a simple Sinatra app where I've defined a Tweets model and using mongoid's dynamic attributes I'm able to quickly output values from the document as follows:

<% @tweets.each do |tweet| %>
<li><%= tweet._id %></li>
<li><%= tweet.user.screen_name %></li>
<li><%= tweet.entities %></li>

When I try to output a value like

<li><%= tweet.entities.urls %></li>

I start to see errors where the method does not exist. The "tweet.entities" call on it's own will return the contents of the nested embed. Does anyone have any ideas as to how I can check for the existence of the child embed so I can then traverse down into it? Is what I'm trying to do even possible with mongoid? My query at the moment just returns the full document.

Lycha
  • 9,937
  • 3
  • 38
  • 43
Colm Troy
  • 1,947
  • 3
  • 22
  • 35

1 Answers1

1

The best in your case is override the entites method to return an empty Entity model if there are no entities key. Or you can create a new methode entities_url doing the job of check ifg there are url and or and return value if there are url

class Tweet

  def entities
    super || Entity.new
  end

  def entities_url
    entities.respond_to?(:url) ? entities.url : ''
  end

end
shingara
  • 46,608
  • 11
  • 99
  • 105
  • thanks shingara - I was thinking a method ti check if a url exists or not might be the way to go. At the moment in my app - I've just defined a Tweet class. I've not defined an entities class - I'm using mongoid's dynamic fields to access the entities embed - I tried your code just now and it's not picking up any urls - I'm thinking I probably need to define and Entity class/model now - sorry if my lack of ruby experience is a factor! – Colm Troy Mar 05 '12 at 10:35
  • You can do the same without Entity model, You can by example return a Hash with empty value on 'url' key by example. It's just return a value with valid duck typing. To have some "more confident code" see the @avid talk about that. – shingara Mar 05 '12 at 11:12
  • cheers shingara - that's very helpful. I've accepted your answer. I also managed to better understand how the data is returned to ruby from mongo via mongoid and was able to drill down into the embeds with – Colm Troy Mar 05 '12 at 11:35
  • ...with <% tweet["entities"]["urls"].each do |url| %> <%= url["display_url"] %> – Colm Troy Mar 05 '12 at 11:42