Ruby - undefined method `extract_options!' : Array - ruby-on-rails

While running following sample using TweetStream I am getting mentioned error.
tweets.rb
require 'tweetstream'
TweetStream.configure do |config|
config.consumer_key = '<CONSUMER KEY>'
config.consumer_secret = '<CONSUMER SECRET>'
config.oauth_token = '<OAUTH TOKEN>'
config.oauth_token_secret = '<OAUTH TOKEN SECRET'
config.auth_method = :oauth
end
TweetStream::Client.new.track('ruby') do |status|
puts "#{status.text}"
end
Error
$ ruby tweets.rb
/home/amit/.rvm/gems/ruby-1.9.3-p194/gems/tweetstream-2.3.0/lib/tweetstream/client.rb:96:in `track': undefined method `extract_options!' for ["ruby"]:Array (NoMethodError)
from tweets.rb:11:in `<main>'
https://github.com/intridea/tweetstream
Am I missing something?

Here's another solution: opening up Array class and defining extract_options! method on it.
Add the following code :
class Array
def extract_options!
last.is_a?(::Hash) ? pop : {}
end unless defined? Array.new.extract_options!
end
to the beginning of the tweets.rb file or to a separate file (which would
need to be required in the tweets.rb file).

extract_options! is ActiveSupport method. If it's not rails app you need to install it and include into script.

I am too late to answer but i think it'll be useful for ruby naive programmers like me.
To include ActiveSupport method like extract_options!, you need to include Active Support.
require 'active_support'
And if you want to include ruby gems then include rubygems too.
require 'rubygems'

Related

How do I identify out the global Rails settings in a custom COP?

My cop:
# lib/rubocop/cop/myproject/my_cop.rb
require 'rubocop'
module RuboCop
module Cop
module MyProject
class MyCop < RuboCop::Cop::Cop
# ...
end
end
end
end
This cop needs to know some global settings Rails. For example, Rails.logger.log_level
But I get errors:
1) undefined method 'logger' for RuboCop::Cop::Rails:Module - when I call Rails.logger.log_level
2) uninitialized constant Rails - when I call ::Rails.logger.log_level
Can this be done or is it a stupid idea?
As an option you can do:
# lib/rubocop/cop/myproject/my_cop.rb
require 'rubocop'
require_relative '../../../../../config/environment'
module RuboCop
module Cop
module MyProject
class MyCop < RuboCop::Cop::Cop
# ...
end
end
end
end
And call ::Rails.logger.level
Rubocop is a static code analyzer. Which means when you run rubocop command, it does not load any ruby environments, including Rails. It just reads ruby files and analyses those as text files.
So the short answer is: no, it can not be achieved with Rubocop.

NameError - uninitialized constant Zip

I am trying to unzip a file in my Spree plugin.
Defined the unzipping method in a module which looks like this.
module ImportImages
class Zipper
def self.unzip(zip, unzip_dir, remove_after = false)
Zip::File.open(zip) do |zip_file|
zip_file.each do |f|
f_path=File.join(unzip_dir, f.name)
FileUtils.mkdir_p(File.dirname(f_path))
zip_file.extract(f, f_path) unless File.exist?(f_path)
end
end
FileUtils.rm(zip) if remove_after
end
end
end
I have included the rubyzip gem in my Gemfile.
gem 'rubyzip'
gem 'zip-zip'
When trying to run it, I am getting the following error.
NameError - uninitialized constant ImportImages::Zipper::Zip:
I have tried every solution provided in stackoverflow and other sites. I tried downgrading the version of rubyzip which is 1.2.0 now and add require 'zip' or require 'zip/zip'. Both returned load error.
I have try adding require 'zip/filesystem' to the class. But got
LoadError - cannot load such file -- zip/zipfilesystem
Any solution for this?
Include rubyzip in gem file in this way:
gem 'rubyzip', require: 'zip'
See this question
It's looking for a nested Constant. Change line Zip::File.open(zip) do |zip_file| with below:
::Zip::File.open(zip) do |zip_file|
It should work.
Also make sure you require rubygem/bundle setup. Though in spree it should've already been done.
Babar's answer is correct, but you also need to add require 'zip' in application_controller.rb

include file ruby selenium

I have multiple ruby test cases for selenium-webdriver and all the files are sharing the same functions. is there any way to create a global file and include the file to these test cases instead of typing them over and over again
for example - I create a file setup.rb
def setup
#driver = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
end
then in my test_file.rb I start
require setup
setup
#driver.find_element(:xpath => '//span[text()="войти"]').click
There is an error
NoMethodError:
undefined method `find_element' for nil:NilClass
Change it to a global variable from an instance variable. Make it $driver instead of #driver and you shouldn't have a problem. Change it to something like..
def self_setup
$driver = Selenium::WebDriver.for :firefox
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
end
and then
require "./setup.rb"
setup.setup
$driver.find_element(:xpath => '//span[text()="войти"]').click
That should work. You'd probably want to go to a page first before you look for that xpath though. setup will only open up a new instance of firefox webdriver. Also I would suggest changing the name of setup.rb so it can be foo.setup insead of setup.setup. I use Lib.rb for the methods I want to be able to call regularly so for instance one would be Lib.signin_admin
Hope this works for you.
In response to your example, I think you forgot to include the setup module (you did put your method definition inside a module, right?). Also, the comment that mentions assigning the driver as a global variable (by naming it with a starting dollar sign) is a good idea. So things would look like this...
setup.rb
module Setup
def setup
$driver = Selenium::WebDriver.for :firefox
$wait = Selenium::WebDriver::Wait.new(:timeout => 10)
end
end
test_file.rb
require 'setup'
class SeleniumTest < Test::Unit::TestCase
include Setup # Modules need to be included (mixed-in) in order to be used inside classes
# Setup is automagically called when using TestUnit
$driver.get "http://www.yoururl.com"
$driver.find_element(:xpath => '//span[text()="войти"]').click
end
The downside is that for each new module and file you create, you have to require and include all of the new files and modules you want to use.
The method that I have found to work for me is to create a 'test_helper.rb', and to use a gem called 'require_all' that requires and includes all of the files from the directories you specify.
My test_helper.rb looks something like this:
require "rubygems"
require "require_all"
require "selenium-webdriver"
require "test-unit"
require_all relative_path("../lib/selenium/")
module TestHelpers
include Selenium
def setup
$driver = Selenium::WebDriver.for :firefox
...
end
def teardown
$driver.quit
end
end
And the test_page.rb only requires two lines:
# Line 1: Ensures the test_helper.rb gets loaded from the same directory the test_page.rb resides in
require File.join(File.dirname(__FILE__), 'test_helper')
class TestPage < Test::Unit::TestCase
# Line 2: Module needs mixed in to use its methods
include TestHelpers
def test_page
$driver.get "http://www.mysite.com"
assert $driver.find_element(:css => "div#my_site_logo")
end
end

delayed_job gives "NameError: uninitialized constant"

I'm trying to move a current working task (in production and in the console) to use delayed_job in a Rails 2 app but keep getting the error:
ThermalImageJob failed with NameError: uninitialized constant Barby::Code128B
I've pored through others' code searching for an answer to no avail. Here's my code:
/lib/thermal_image_job.rb
class ThermalImageJob < Struct.new(:order_id)
def perform
order = Order.find(order_id)
order.tickets.each do |ticket|
ticket.barcodes.each do |barcode|
barcode.generate_thermal_image
end
end
end
end
/app/controllers/orders_controller.rb
Delayed::Job.enqueue(ThermalImageJob.new(#order.id))
/app/models/barcode.rb
def generate_thermal_image(format=:gif)
filename = "#{barcode}_thermal.#{format}"
temp_file_path = File.join("#{RAILS_ROOT}", 'tmp', filename)
unless FileTest.exists?(temp_file_path)
barcode_file = File.new(temp_file_path, 'w')
code = Barby::Code128B.new(barcode)
....
end
Gemfile
gem "delayed_job", "2.0.7"
gem "daemons", "1.0.10"
Well, after much head banging, I figured it out, so I'm posting this to help the next person. The problem was that it couldn't find the barby libs, so I added a require at the beginning of my class:
require "barby/outputter/rmagick_outputter"
require "barby/barcode/code_128"

Why am I getting a nil object instead of a shortlink from bitly?

I'm using a simple enough bitly implementation based on this example: http://www.appelsiini.net/2010/using-bitly-with-httparty
I put this file in the lib folder (bitly.rb)
require 'rubygems'
require 'httparty'
class Bitly
include HTTParty
base_uri "api.bit.ly"
##login = "goldhat"
##api_key = "R_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
def self.shorten(url)
response = get("/v3/shorten?login=#{##login}&apiKey=#{##api_key}&longUrl=#{url}")
response["data"]["url"]
end
end
For some reason I'm getting a nil object. As though bitly doesn't even respond with any data. I tested it out in my console and my app and get the same error:
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
from c:/goldhat_production/lib/bitly.rb:9:in `shorten'
from (irb):1
Any ideas?
Alternative to the DIY - you can find a well-tested Ruby gem for bit.ly here.
The problem isn't the Bitly code, it's that you're putting it in the lib/ directory in a Rails 3 application. To get lib/ loaded, you need the following in config/application.rb:
config.autoload_paths += %W(#{config.root}/lib)

Resources