Javi Moreno Apuntes Fichas de Lectura Archivo Sobre mi
Blog Logo

Javi


4 minutos de lectura

Como era de esperar, el debut de URLHunter ha tenido alguna incidencia.
En un primer momento pensé que todo era provocado por unos cambios de ultima hora que tuve que hacer en los tipos de campo de la entidad Tweetlinks al pasar de SQLite a PostgreSQL pero no, el problema ha sido de programador despistado.

Este es el método que se encarga de la grabación de los tweets en el modelo. Según el API de Twitter, cada tweet retweeteado estará contenido dentro de otro tweet. El tweet padre siempre pertenecerá al usuario que hace el retweet mientras que la información original estará en el anidado. Esta es la razón por la que al preguntar si el tweet es en realidad un retweet hay que hacer una sustitución del objeto tweet. El problema ha sido que la comprobación de que el tweet_id no existe en la tabla se hacía antes del cambio por lo que, en realidad, el que se terminaba grabando siempre era otro.

def self.insert_tweet(tweet)
 unless exists?(tweet_id: tweet.id)
   if tweet.retweet?
     tweet = tweet.retweeted_status
   end
   if tweet.urls.any?
     create!(
         tweet_id: tweet.id,
         content: tweet.text,
         screen_name: tweet.user.screen_name,
         profile_image: tweet.user.profile_image_url,
         tweet_created_at: tweet.created_at,
     )
   end
 end
end

Este sería el código correcto:

def self.insert_tweet(tweet)
 if tweet.retweet?
   tweet = tweet.retweeted_status
 end
 unless exists?(tweet_id: tweet.id)
   if tweet.urls.any?
     create!(
         tweet_id: tweet.id,
         content: tweet.text,
         screen_name: tweet.user.screen_name,
         profile_image: tweet.user.profile_image_url,
         tweet_created_at: tweet.created_at,
     )
   end
 end
end

A veces sucede que un error compensa a otro error y esto es lo que ha pasado esta vez. Al incluir la paginación, se me olvido incluir un criterio de ordenación en la query correspondiente. Debido a esto, el orden de presentación era por inserción (ascendente). En la carga inicial se recuperan 200 tweets pero se empiezan a insertar de más reciente a más antiguo. Posteriormente, cada llamada a la página recupera los nuevos tweets y si corresponde insertarlos los inserta.
A lo largo de la mañana se podía ver como el número de páginas iba subiendo de seis hasta once que es a lo que ha llegado hasta que he podido hacer un pequeño arreglo en Heroku. Básicamente las cinco nuevas páginas contenían el mismo tweet, en concreto el RT de mi tweet de presentación... vamos un debut lamentable ;-)

def home

  @tweetlinks = Tweetlink.paginate(page: params[:page])

  @tweetlinks.empty? ? Tweetlink.first_time : Tweetlink.pull_tweets

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @tweetlinks }
  end

end

Este sería la forma correcta:

def home

  @tweetlinks = Tweetlink.paginate(page: params[:page]).order('tweet_id DESC')

  @tweetlinks.empty? ? Tweetlink.first_time : Tweetlink.pull_tweets

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @tweetlinks }
  end

end

¿Cómo lo he podido arreglar sin tocar el código?

Una vez identificado el problema, y viendo que los amigos de @ObjectiveC_es habían tweeteado algún enlace más lo único que había que hacer era hacer un rollback de la base de datos, borrarla completamente y volverla a crear. La primera carga de la base de datos recuperaría hasta un tweet normal y mientras no hicieran otro retweet de un enlace no se volvería a producir el problema.

Por los pelos, la próxima vez seré más prudente y hare una beta. :-)