Search code examples
ruby-on-railsruby-on-rails-4sidekiq

Sidekiq: ArgumentError: When assigning attributes, you must pass a hash as an argument


I guess this question is common with Rails 4, but my situation is different.

I am using Sidekiq to delay the creation of jobs; think this is possible as with simple data, it works. By means of simple data:

def perform
 Foo.create(bar: "staff")
end

Here's my data with issues:

supports_controller.rb:

def create
 params = support_params // seems to be issues here?
 DelayedJobs.perform_in(1.minutes, current_user.id, params)
 ...
end

private

  def support_params
   params.require(:support).permit(:foo1, :foo2, :foo3)
  end

app/workers/delayed_jobs.rb:

class DelayedJobs
  include Sidekiq::Worker
  def perform(user_id, params)
    u = User.find(user_id)
    support = u.supports.build(params)
    Support.create(support) // create and save to db
  end
end

Via web (localhost:3000/sidekiq/scheduled, I see the details. Great. But after a minute it goes to retries with the error. Any help on this one?

EDIT:

In the sidekiq web argument:

40, {"foo1"=>"a", "foo2"=>"b", "foo3"=>"c"}

Why is that the user_id (40) is outside?


Solution

  • The problem isn't with Sidekiq; it's an ActiveRecord problem with this line:

    Support.create(support)

    create only takes a hash, but you're giving it a Support.

    This should work:

    class DelayedJobs
      include Sidekiq::Worker
      def perform(user_id, params)
        u = User.find(user_id)
        u.supports.create!(params) # `create!` will raise an error if the save fails; allowing you to catch invalid params
      end
    end
    

    Protip: you can eliminate Sidekiq as a suspect by running the body of your perform method in a Rails console. You'll see that you get the same error even when Sidekiq isn't involved.