Rails ArgumentError on Job - wrong number of arguments - how to debug? - ruby

I’m trying to create a Job within my specs with the following, but keep getting an ArgumentError:-
MyJob.new.perform_now(user_id: #current_user.id, building_ids: [building.id])
module ActionPlan
class MyJob < ApplicationJob
queue_as :low
def perform(user_id:, building_ids:, **_args)
#user = User.find(user_id)
#buildings = ActionPlan::Reminder.where(user_id: user_id)
#buildings.map(&method(:create_alerts))
end
I keep getting wrong number of arguments (given 1, expected 0) (ArgumentError). Where am I going wrong? The perform method takes 2 arguments, right? How would I debug this?

Try this:
module ActionPlan
class MyJob < ApplicationJob
queue_as :low
def initialize(user_id:, building_ids:, **_args)
#buildings = ActionPlan::Reminder.where(user_id: user_id)
end
def perform
buildings.map(&method(:create_alerts))
end
private
attr_accessor :buildings
end
end
That should allow you to call:
MyJob.new(user_id: #current_user.id, building_ids: [building.id]).perform

Related

How I create a simples questionnaire with Lita.io?

I try implementing a little questionnaire in Lita as the sample:
For which system do you want to open a call?
SYSInitials
What's your problem?
I forgot my password
Thanks! Your call was opened!
Any help how I can do this?
So, I'm try this:
module Lita
module Handlers
class Helpdesk < Handler
on :shut_down_complete, :clear_context
route(/^abrir chamado$/i, :abrir_chamado)
route(/^.*$/i, :motivo)
http.get '/info', :web
def motivo(response)
return unless context == 'abrir_chamado'
response.reply('Thanks! Your call was opened!')
clear_context
end
def abrir_chamado(response)
redis.set(:context, :abrir_chamado)
user = response.user
response.reply(
%(Hello #{user.name}, What is your problem?)
)
end
def context
#contetx ||= redis.get(:context)
end
def clear_context
redis.del(:context)
end
Lita.register_handler(Helpdesk)
end
end
end
But when I register, :informar_motivo route, after passing of the :abrir_chamado route, is matched :informar_motivo route too.
but I need:
me: abrir chamado
Lita: Hello Shell User, What is your problem?
me: I forgot my password
Lita: Thanks! Your call was opened!
I found a ugly solution, but works :P
module Lita
module Handlers
class Helpdesk < Handler
on :shut_down_complete, :clear_context
on :unhandled_message, :motivo
route(/^abrir chamado$/i, :abrir_chamado)
http.get '/info', :web
def motivo(payload)
response = payload[:message]
return unless context == 'abrir_chamado'
response.reply('Thanks! Your call was opened!')
clear_context
end
def abrir_chamado(response)
redis.set(:context, :abrir_chamado)
user = response.user
response.reply(
%(Hello #{user.name}, What is your problem?)
)
end
def context
#contetx ||= redis.get(:context)
end
def clear_context
redis.del(:context)
end
Lita.register_handler(Helpdesk)
end
end
end

Ruby tests don't run

I'm trying Ruby and Unit Testing but my simple attempts at running test cases are returning nothing. The curious thing is that the tests were running before and returning the number of tests that were ran and the number of assertions and so on. But for some reason they stopped running. I have two separated files:
#TipoMovimento.rb
class TipoMovimento
attr_accessor :designacao
attr_accessor :cor
attr_accessor :regras
def initialize(aDesignacao, aCor, asRegras)
#designacao = aDesignacao
#cor = aCor
#regras = asRegras
end
def ==(other)
other.class == self.class && other.state == self.state
end
def state
self.instance_variables.map { |variable| self.instance_variable_get variable }
end
end
and
#TesteTipoMovimento.rb
require './TipoMovimento.rb'
require 'test/unit'
class TesteTipoMovimento < Test::Unit::TestCase
def setup
#tm = TipoMovimento.new('Des1', 'Cor1', ['r1', 'r2'])
end
def tc_equal
tm2 = TipoMovimento.new('Des1', 'Cor1', ['r1', 'r2'])
assert_true(tm2 == #tm)
tm2 = TipoMovimento.new('Des2', 'Cor1', ['r1', 'r2'])
assert_false(tm2 == #tm)
end
end
Both files are in the same folder. Unfortunately, when I run the test file, nothing happens. After I press enter the prompt simply ignores my command. Something like:
C:\My Ruby Files\>ruby TesteTipoMovimento.rb
C:\My Ruby Files\>
This is obviously something simple that I'm missing, so if anyone could help me I would appreciate it. Thanks!
You have no tests in that test class. To make method a test, prefix its name with test_.
class TesteTipoMovimento < Test::Unit::TestCase
def setup
#tm = TipoMovimento.new('Des1', 'Cor1', ['r1', 'r2'])
end
def test_tc_equal
tm2 = TipoMovimento.new('Des1', 'Cor1', ['r1', 'r2'])
assert_true(tm2 == #tm)
tm2 = TipoMovimento.new('Des2', 'Cor1', ['r1', 'r2'])
assert_false(tm2 == #tm)
end
end

wrong number of arguments ruby rspec

I'm trying to write unit tests for my code using rspec. I keep getting a "wrong number of arguments" error:
class MyClass
attr_accessor :env, :company,:size, :role, :number_of_hosts,:visability
def initialize(env, company, size, role, number_of_hosts, visability)
#env, #company, #size, #role, #number_of_hosts, #visability = env, company, size, role, number_of_hosts, visability
end
end
And here are my tests:
require_relative "../lib/MyClass.rb"
describe MyClass do
it "has an environment" do
MyClass.new("environment").env.should respond_to :env
end
it "has a company" do
MyClass.new("company").company.should respond_to :company
end
...
When I run rspec I get:
1) MyClass has an environment
Failure/Error: MyClass.new("environment").env.should respond_to :env
ArgumentError:
wrong number of arguments (1 for 6)
# ./lib/MyClass.rb:4:in `initialize'
# ./spec/MyClass_spec.rb:5:in `new'
# ./spec/MyClass_spec.rb:5:in `block (2 levels) in <top (required)>'
...
What am I missing?
EDIT
Sergio helped thanks...however
Sergio's answer worked...although I still have a further question:
Given the Class:
class Team
attr_accessor :name, :players
def initialize(name, players = [])
raise Exception unless players.is_a? Array
#name = name
raise Exception if #name && has_bad_name
#players = players
end
def has_bad_name
list_of_words = %w{crappy bad lousy}
list_of_words - #name.downcase.split(" ") != list_of_words
end
def favored?
#players.include? "George Clooney"
end
end
and spec...
require_relative "../lib/team.rb"
describe Team do
it "has a name" do
Team.new("random name").should respond_to :name
end
it "has a list of players" do
Team.new("random name").players.should be_kind_of Array
end
...
The tests pass without the same error...(This works fine: Team.new("random name"))
Any explanation?
Here is the error MyClass.new("environment"). As you have written def initialize(env, company, size, role, number_of_hosts, visability). So you should pass 6 parameters when you are calling MyClass#new method. But in practice you pass only one which is "environment". Thus you got the legitimate error - wrong number of arguments (1 for 6).

Testing before_create method in rspec and rails 3

I've looked into some tutes and all I saw were old posts on how to test before_create. Also it seems like they're all just testing that before_create was called i.e.:
#user = User.new
#user.should_receive(:method_name_called_by_before_create)
#user.send(:before_create) (sometimes they just do #user.save)
I want to actually test that my method worked and that it had assigned(and saved the variables) after creating the record.
Here are my models:
user.rb
class User < ActiveRecord::Base
has_one :character, :dependent => :destroy
after_create :generate_character
private
def generate_character
self.create_character(:name => "#{email}'s avatar")
end
end
and character.rb
class Character < ActiveRecord::Base
belongs_to :user
before_create :generate_character
private
def generate_character
response = api_call
#API CALL HERE
#set object attributes here
self.stat1 = calculate_stat1(response) + 5
self.stat2 = calculate_stat2(response) + 5
self.stat3 = calculate_stat3(response) + 5
end
def api_call
return api_call_response
end
end
I want to test that generate character indeed set the attributes without going online and calling the API call. Is this possible with rspec? I have a fixture of a json response so I was hoping I can stub out generate character and then use the fake response for testing.
Here's my character.spec:
describe Character do
before(:each) do
Character.any_instance.stub!(:api_call).and_return(fake_response.read)
#user = Factory(:user)
#character = #user.character
puts #character.inspect
end
def fake_response
File.open("spec/fixtures/api_response.json")
end
It prints out only 5 for each of the character's stats. Also I did a puts response in the generate_character method in character.rb and it still prints out the "real" api call.
I managed to do a puts in fake_response and it does goes through there but it also goes through the "real" api_call after, which makes the stub obsolete. How do I get through this?
A good approach here is extracting your api call into a self contained method. Something like this:
class Character < ActiveRecord::Base
belongs_to :user
before_create :generate_character
private
def generate_character
data = api_call
#set object attributes from data
end
def api_call
# returns a data structure
# resulting from the call
end
end
Then use RSpec's any_instance to stub the api_call method to return a fixed data structure
Character.any_instance.stub!(:api_call).and_return { {:id => 1, :attribute_one => "foo"} }
#user = User.create
#user.character.attribute_one.should == "foo"
for more info on any_instance check this commit

How to extend DataMapper::Resource with custom method

I have following code:
module DataMapper
module Resource
##page_size = 25
attr_accessor :current_page
attr_accessor :next_page
attr_accessor :prev_page
def first_page?
#prev_page
end
def last_page?
#next_page
end
def self.paginate(page)
if(page && page.to_i > 0)
#current_page = page.to_i - 1
else
#current_page = 0
end
entites = self.all(:offset => #current_page * ##page_size, :limit => ##page_size + 1)
if #current_page > 0
#prev_page = #current_page
end
if entites.size == ##page_size + 1
entites.pop
#next_page = (#current_page || 1) + 2
end
entites
end
end
end
Then I have call of #paginate:
#photos = Photo.paginate(params[:page])
And getting following error:
application error
NoMethodError at /dashboard/photos/
undefined method `paginate' for Photo:Class
In Active record this concept works fine for me... I'am using JRuby for notice. What I'am doing wrong?
Andrew,
You can think of DataMapper::Resource as the instance (a row) and of DataMapper::Model as the class (a table). Now to alter the default capabilities at either the resource or the model level, you can either append inclusions or extensions to your model.
First you will need to wrap your #paginate method in a module. I've also added a probably useless #page method to show how to append to a resource in case you ever need to.
module Pagination
module ClassMethods
def paginate(page)
# ...
end
end
module InstanceMethods
def page
# ...
end
end
end
In your case, you want #paginate to be available on the model, so you would do:
DataMapper::Model.append_extensions(Pagination::ClassMethods)
If you find yourself in need of adding default capabilities to every resource, do:
DataMapper::Model.append_inclusions(Pagination::InstanceMethods)
Hope that helps!

Resources