如何让这个resque工作起作用?

时间:2011-09-22 17:54:44

标签: ruby-on-rails ruby resque

我希望Resque工作人员通过Viralheat API获取品牌实例标签的情绪 (在后台属于User),然后将该响应的mood参数保存到Tag。

更新

我修改了代码,现在工作程序失败了,因为它为nil:NilClass表示未定义的方法score。这种情况正在发生,因为ActsAsTaggableOn::Tagging.find_by_tag_id(tag.id).score.create没有tag.id来检查,我也不认为.create是有效的Ruby。

Viralheat API响应(JSON)格式:

{"prob":0.537702567133646,"mood":"positive","text":"hello, goodbye"}

控制器

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工人

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

标记表

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

2 个答案:

答案 0 :(得分:2)

您的参数列表中有拼写错误:def self.perform(tag.id, user_id)应为def self.perform(tag_id, user_id)(请注意下划线)。

更新

您不应该在Resque Job中使用实例变量。在声明之前,您实际上正在尝试使用@brand

您正试图从params获取信息。没有请求,因此没有params。您可能希望使用tag_id参数替换该find参数。

您排队参数的顺序正在被翻转。您的enqueue来电正在user_id之前指定tag_id。这项工作期待tag_id之前的user_id

自从您更新了问题后,您已将tag_id参数更改为tags_id。我不知道你是否意识到这一点,但是调用brand.tags.id可能只返回一个id(我对acts_as_taggable不太熟悉)。

答案 1 :(得分:0)

步骤1 - 修复您的控制器,使其仅在成功时运行作业。

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."
    #update was successful, create the job
    Resque.enqueue(SentimentJob, @brand.tags)
  else
    render :action => 'edit'
  end
end

第2步 - 修复你的表格列,你不能在heroku上使用带有PG的Camel Case命名,在早期的帖子中看到你在heroku上,这会给你带来问题。

所以运行rails g migration FixColumnName

进入db / migrate文件夹并找到迁移

将其粘贴到其中

class FixColumnName < ActiveRecord::Migration
  def self.up
    rename_column :taggings, :Sentiment, :sentiment
  end

  def self.down
    # rename back if you need or do something else or do nothing
  end
end

运行rake db:migrate

第3步 - 修复您的工作人员,使其完成您希望的工作。

请注意 - 我完全忽略了您的“得分”方法,因为您的代码中没有提及它,并且您没有在问题的任何地方说出它的用途或应该做什么。

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          


    #find the tag
    @tag = ActsAsTaggableOn::Tagging.find_by_tag_id(tag.id)

    #set the tags value for the field sentiment to @sentiment_response[:mood]
    @tag.sentiment = @sentiment_response[:mood]

    #save the tag
    @tag.save

    end
  end
end