I want to have a Resque worker get sentiment via the Viralheat API for tags for a brand instance
(belongs to User) in the background, and then save the mood parameter of that response to a Tag.
Update:
I’ve revised the code and now the worker fails because it says undefined method score for nil:NilClass. That’s happening because ActsAsTaggableOn::Tagging.find_by_tag_id(tag.id).score.create has no tag.id to check against, also I don’t think .create is valid Ruby.
Viralheat API response (JSON) format:
{"prob":0.537702567133646,"mood":"positive","text":"hello, goodbye"}
Controller:
def update
@brand = Brand.find(params[:id])
current_user.tag(@brand, :with => params[:brand][:tag_list], :on => :tags)
if @brand.update_attributes(params[:brand])
redirect_to :root, :notice => "Brand tagged."
else
render :action => 'edit'
end
Resque.enqueue(SentimentJob, @brand.tags)
end
sentiment_job.rb Worker:
require 'resque-retry'
class SentimentJob
@queue = :sentiment_pull
def self.perform(tags)
tags.each do |tag|
url = "http://www.viralheat.com/api/sentiment/review.json"
@sentiment_response = url.to_uri.get(
:api_key => 'MY KEY',
:text => tag.name.to_s ).deserialize
#If I comment out the 3 lines below, the worker runs and I get 3 successful callbacks but can't save them.
@sentiment_value = @sentiment_response[:mood]
@sentiment_store = ActsAsTaggableOn::Tagging.find_by_tag_id(tag.id).score.create(@sentiment_value)
@sentiment_store.save
end
end
end
Tagggings table:
create_table "taggings", :force => true do |t|
t.integer "tag_id"
t.integer "taggable_id"
t.string "taggable_type"
t.integer "tagger_id"
t.string "tagger_type"
t.string "context"
t.datetime "created_at"
t.string "Sentiment"
end
You have a typo in your argument list:
def self.perform(tag.id, user_id)should bedef self.perform(tag_id, user_id)(note the underscore).Update
You shouldn’t be using instance variables in a Resque Job. You are actually trying to use
@brandbefore you declare it.You are trying to get information from
params. There is no request, and thus noparams. You probably want to swap out that find argument with thetag_idargument.The order you are queueing arguments is getting flipped. Your
enqueuecall is specifying theuser_idbefore thetag_id. The job is expecting thetag_idbefore theuser_id.And since you updated your question, you have switched the
tag_idargument intotags_id. I don’t know if you realize this, but callingbrand.tags.idwill probably return just a single id (I’m not too familiar withacts_as_taggable).