Ruby undefined method each - ruby-on-rails

i am new to ruby language and i tried to learn it now.
i have a classCompany with method find_applicants
class Company
attr_accessor :jobs
## TODO: This method should update the `jobs` property to an array of instances of
## class `Job`
def initialize(jobs)
# Load the json file and loop over the jobs to create an array of instance of `Job`
# Assign the `jobs` instance variable.
#jobs = jobs
end
## TODO: Impelement this method to return applicants from all jobs with a
## tag matching this keyword
def find_applicants(keyword)
# Use the `jobs` instance variable.
applicants = []
#jobs.each do |job|
job.applicants.each do |applicant|
applicant.tags.each do |tag|
if keyword.eql? tag
# ...
end
end
end
end
end
and the main.rb
require './src/company.rb'
require './src/applicant.rb'
require './src/job.rb'
require 'json'
company = Company.new('data/boundless.json')
applicants = company.find_applicants('google')
puts applicants
and when compile this i have this error
/Users/user/Desktop/BoundlessCaseStudy/src/company.rb:34:in find_applicants': undefined methodeach' for nil:NilClass (NoMethodError)
from main.rb:11:in `'
please help

Looks like you are passing the name of the json file where the jobs are, instead an array of jobs
company = Company.new('data/boundless.json')
but you did no wrote que code that parse this file, as the comment correctly says you should
# Load the json file and loop over the jobs to create an array of instance of `Job`,
So the variable #jobs is receiving a string, and you will get this error:
NoMethodError: undefined method `each' for "data/boundless.json":String
write the code to parse the file and set the #jobs variable correctly

Related

Rspec "NoMethodError" from nested module

I'm running into a weird error:
Class:
module AnimalSanctuary
module AnimalInspector
class AnimalPicker
def initialize(number_of_animals, ids)
#number_of_animals = number_of_animals
#ids = ids
end
...
def pick_animals(animal)
end
end
end
test:
require 'rails_helper'
RSpec.describe AnimalSanctuary::AnimalInspector::AnimalPicker do
describe ".pick_animals" do
context "pick an available animal" do
it "returns animal name" do
expect(AnimalSanctuary::AnimalInspector::AnimalPicker.pick_animals("Dog")).to eq("Dog")
end
end
end
end
I get the following error:
NoMethodError:
undefined method `pick_animals' for AnimalSanctuary::AnimalInspector::AnimalPicker:Class
Rspec calls the class but not the method which has stumped me. Am I doing something wrong?
The definition of pick_animals is an instance method.
To call it, you will need to instantiate an object of the class using the new method as shown below. I have passed in random values to your initializer (1, [1,2]) however you can set them as you like.:
number_of_animals = 1
ids = [1,2]
AnimalSanctuary::AnimalInspector::AnimalPicker.new(number_of_animals, ids).pick_animals("Dog")
Otherwise, to call it the way you are calling it, you will need to redefine it as a class method by using self.pick_animals as shown below:
module AnimalSanctuary
module AnimalInspector
class AnimalPicker
...
def self.pick_animals(animal)
end
end
end
yeah pick_animals is an instance method.
you can use the following in your rspec
expect_any_instance_of(nimalSanctuary::AnimalInspector::AnimalPicker).to receive(:pick_animals).with("dogs").to_eq("Dog")
Hope this helps

How do I add a method to ActiveRecord::Batches use include

environment: rails 4.2, ruby 2.2.0
I was trying to add function something like find_each, but order by id descending.
I want to use it like this.
Person.where('age > 30').find_each_desc.each do |person|
end
I add method to ActiveRecord::Batches, it works great.
# file config/initializers/active_record.rb
module ActiveRecord
module Batches
def find_each_desc(options = {})
# do something
end
end
end
But if move to anthoer module, use include to add method, it's not working.
# file util/find_in_batches_with_order.rb
module Util
module FindInBatchesWithOrder
def find_each_desc(options = {})
# do something
end
end
end
# file config/initializers/active_record.rb
module ActiveRecord
module Batches
include Util::FindInBatchesWithOrder
end
end
# can get find_each_desc method
$ ActiveRecord::Batches.instance_methods
=> [:find_each, :find_in_batches, :find_each_desc]
ActiveRecord::Relation include ActiveRecord::Batches, so can find find_each_desc method in ActiveRecord::Relation instance methods, but not.
How should I do?

Undefined local variable or method for module

I have module CurrencyExchange with following methods
CURRENCIES = %w(uah rub eur usd)
def available_currencies
CURRENCIES.join(' ').downcase.split.permutation(2)
end
and when i want to use available_currencies with
define_method
available_currencies.each do |(c1, c2)|
define_method(:"#{c1}_to_#{c2}") do |cr| ... end end
i have got an error
undefined local variable or method `available_currencies'
for CurrencyExchange:Module (NameError)
but when i use it like
CURRENCIES.join(' ').downcase.split.permutation(2).each do |(c1, c2)|
define_method(:"#{c1}_to_#{c2}") .... end end
it works fine
Why it happens?
I think you need to write def self.available_currencies
You try to create other method in the class and Ruby searches in the loop for a class method .available_currencies.
You have to change your class method .available_currencies into a instance method #available_currencies or create the methods in your initializer.
Method 1:
class MyClass
def self.available_currencies
# Your logic...
end
# Your logic...
end
Method 2:
class MyClass
def init
available_currencies.each do |c|
define_method(c) do
# Whatever you want to do ...
end
end
end
def available_currencies
# Your logic...
end
end
I would recommend you the first way since you maybe want to use the currencies in classes. I would recommend you the second way, if you want for example different currencies for different instances.
Happy coding :)

Why sidekiq returned error?

I trying to use sidekiq in my app, but when I write this simple worker
class ParseWorker
include Sidekiq::Worker
def perform(instance)
instance.spideys << Spidey.create
end
end
and I use this worker here
def create
#user_link = UserLink.new(user_link_params)
if #user_link.save
binding.pry
ParseWorker.perform_async(#user_link)
redirect_to results_user_links_path
end
end
was returned the error
2015-04-09T13:14:56.757Z 11644 TID-ay1nc ERROR: Actor crashed!
NoMethodError: undefined method `spideys' for "#<UserLink:0x007f65f00d99b0>":String
/home/weare138/simple-parser/app/workers/parse_worker.rb:7:in `perform'
but why? #user_link is not a string
how fix?
upd
def perform(id)
user_link = UserLink.find(id)
user_link.spideys << Spidey.create
end
error
2015-04-09T14:15:21.889Z 11644 TID-ay1nc ERROR: Actor crashed!
NoMethodError: undefined method `spideys' for 39:Fixnum
upd2
class ParseWorker
include Sidekiq::Worker
require 'open-uri'
def perform(id)
user_link = UserLink.find(id)
user_link.spideys << Spidey.create
end
end
Sidekiq uses Redis, so when you pass to the worker an object, it serializes it to JSON.
From the Sidekiq documentation:
This means the arguments to your worker must be simple JSON datatypes
(numbers, strings, boolean, array, hash). Complex Ruby objects (e.g.
Date, Time, ActiveRecord instances) will not serialize properly.
Instead you should do
def create
...
ParseWorker.perform_async(#user_link.id)
end
def perform(id)
UserLink.find(id).spideys << Spidey.create
end

Unable to access library files from controller in rails

I have created a new library file sampler.rb inside the lib folder. Consider this as the content of the file
module Sampler
def sample_tester
"test"
end
end
I have included it in the application_controller and added a require statement in the config\initializers. When I try to access the method sample_tester from my controllers, I get the following error
undefined local variable or method `sample_tester` for #<BlogsController:0xb8fbac8>
Am I missing something?
Since it doesn't look like you are creating an instance of this, my first guess is that you need to define it as a class method so that it can be called like this: Sampler.sample_tester.
In your file you could do it one of two ways:
# first way
module Sampler
def self.sample_tester
"test"
end
end
# second way
module Sampler
class << self
def sample_tester
"test"
end
end
The second way is nicer if you want to define a number of class methods.
if you want to have your module method defined as a class method you need to use extend instead of include:
module Mod
def bla
puts "bla"
end
end
class String
include Mod
end
String.bla rescue puts $! # => undefined method `bla' for String:Class
class String
extend Mod
end
puts String.bla # => bla

Resources