uninitialized constant when running rspec test with concerns used in models - ruby-on-rails

When I run rspec spec/models/football_match_spec.rb I get an uninitialized constant error:
/Users/jamessmith/project/app/models/football_match.rb:3:in `<class:FootballMatch>': uninitialized constant FootballMatch::Type1Fixture (NameError)
from /Users/jamessmith/project/app/models/football_match.rb:1:in `<top (required)>'
from /Users/jamessmith/project/spec/models/football_match_spec.rb:3:in `<top (required)>'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/configuration.rb:1226:in `load'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/configuration.rb:1226:in `block in load_spec_files'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/configuration.rb:1224:in `each'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/configuration.rb:1224:in `load_spec_files'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/runner.rb:97:in `setup'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/runner.rb:85:in `run'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/runner.rb:70:in `run'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/lib/rspec/core/runner.rb:38:in `invoke'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.2.0/exe/rspec:4:in `<top (required)>'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/bin/rspec:23:in `load' from /Users/jamessmith/.rvm/gems/ruby-2.1.2/bin/rspec:23:in `<main>'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `eval'
from /Users/jamessmith/.rvm/gems/ruby-2.1.2/bin/ruby_executable_hooks:15:in `<main>'
Type1Fixture concern:
module Type1Fixture
extend ActiveSupport::Concern
def competitors
[competitor_1, competitor_2]
end
def competitor_1_score
[fhhts || 0, shhts || 0, ethts || 0].reduce(:+)
end
def competitor_2_score
[fhats || 0, shats || 0, etats || 0].reduce(:+)
end
def name_with_scores
if [Fixture::IN_PROGRESS_STATUS, Fixture::COMPLETED_STATUS].include?(status)
"#{competitor_1.name} #{home_team_score} - #{away_team_score} #{competitor_2.name}"
else
"#{competitor_1.name} vs #{competitor_2.name}"
end
end
end
Edited FootballMatch model:
class FootballMatch < Fixture
include Mongoid::Document
include Type1Fixture
end
I've added app/models/concerns to the config.autoload_paths array in environments/test.rb.

This can be caused by not having the correct file name. For Type1Fixture, the file containing the class should be called app/models/concerns/type1_fixture.rb. Is this the case?

Related

Configuration of Rspec terminal output

I am a beginner with Rspec, and I found out my terminal output like this.
It's really in a mess and hard to understand test result.
Unlike the output in official tutorial.
Should I install some tools or modify some configuration?
Update
zombie.rb
class Zombie
attr_accessor :name
def initialize
#name = 'Error_Ash'
end
end
zombie_spec.rb
require "spec_helper"
require "zombie"
#give Class
describe Zombie do
# example
it "is named Class_Ash"
zombie = Zombie.new
zombie.name.should == "Ash"
end
error msg
Coda:rspec_pra Coda$ rspec spec/lib/zombie_spec.rb --format doc
/Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-support-3.4.1/lib/rspec/support.rb:87:in `block in <module:Support>': expected: "Ash" (RSpec::Expectations::ExpectationNotMetError)
got: "Error_Ash" (using ==)
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-support-3.4.1/lib/rspec/support.rb:96:in `call'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-support-3.4.1/lib/rspec/support.rb:96:in `notify_failure'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-expectations-3.4.0/lib/rspec/expectations/fail_with.rb:27:in `fail_with'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-expectations-3.4.0/lib/rspec/matchers/built_in/operators.rb:71:in `fail_with_message'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-expectations-3.4.0/lib/rspec/matchers/built_in/operators.rb:106:in `__delegate_operator'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-expectations-3.4.0/lib/rspec/matchers/built_in/operators.rb:91:in `eval_match'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-expectations-3.4.0/lib/rspec/matchers/built_in/operators.rb:51:in `block in use_custom_matcher_or_delegate'
from /Users/Coda/Desktop/code/ruby_pra/rspec_pra/spec/lib/zombie_spec.rb:11:in `block in <top (required)>'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:385:in `module_exec'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:385:in `subclass'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:255:in `block in define_example_group_method'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/dsl.rb:43:in `block in expose_example_group_alias'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/dsl.rb:82:in `block (2 levels) in expose_example_group_alias_globally'
from /Users/Coda/Desktop/code/ruby_pra/rspec_pra/spec/lib/zombie_spec.rb:6:in `<top (required)>'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `load'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `block in load_spec_files'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `each'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `load_spec_files'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:106:in `setup'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:92:in `run'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/bin/rspec:22:in `load'
from /Users/Coda/.rvm/gems/ruby-2.1.3#rails416/bin/rspec:22:in `<main>'
Coda:rspec_pra Coda$
If there is nothing in your spec_helper that somehow overrides the --format switch (which I do not even know if it's possible) then this should give you readable tests that pass:
zombie.rb exactly as you posted,
zombie_spec
require "spec_helper"
require "zombie"
describe Zombie do
it "is named Ash" do
zombie = Zombie.new
expect(zombie.name).to eq "Ash"
end
end
and command rspec spec/lib/zombie_spec.rb -f d which is short for --format documentation
EDIT*: Oh sorry, the Error you posted is indeed an RSpec error... Its just not formated, as you said x.x
try the --tty flag maybe?
rspec spec/lib/zombie_spec.rb --tty -f d

my_zipcode_gem migration generators not working

I'm pretty sure that the problem is due to the fact that this gem looks to be 3-4 years old and rails has changed how we do migrations. But I'm not too familiar with gems/generators. I'm trying to follow the instructions to do the instructions listed here.
rails g my_zipcode_gem:models
rake db:migrate
rake zipcodes:update
However, when I do the first step I end up getting this:
/Users/thammond/.rvm/gems/ruby-2.1.1/gems/my_zipcode_gem-0.1.3/lib/generators/my_zipcode_gem/models_generator.rb:35:in `create_migration': wrong number of arguments (3 for 0) (ArgumentError)
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/generators/migration.rb:63:in `migration_template'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/my_zipcode_gem-0.1.3/lib/generators/my_zipcode_gem/models_generator.rb:36:in `create_migration'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `block in invoke_all'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `each'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `map'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/invocation.rb:133:in `invoke_all'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/group.rb:232:in `dispatch'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/generators.rb:157:in `invoke'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/generate.rb:11:in `<top (required)>'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `block in require'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:232:in `load_dependency'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.0/lib/active_support/dependencies.rb:247:in `require'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:135:in `generate_or_destroy'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:51:in `generate'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /Users/thammond/.rvm/gems/ruby-2.1.1/gems/railties-4.1.0/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Any idea what I need to do to get that gem working? It provides exactly what I'm looking for in my app.
Thanks!
Edit: Adding the generation code:
module MyZipcodeGem
class ModelsGenerator < Base
include Rails::Generators::Migration
source_root File.expand_path('../templates', __FILE__)
def initialize(*args, &block)
super
end
def generate_models
# puts ">>> generate_zipcodes:"
end
def add_gems
add_gem "mocha", :group => :test
end
def create_models
template 'zipcode_model.rb', "app/models/zipcode.rb"
template 'county_model.rb', "app/models/county.rb"
template 'state_model.rb', "app/models/state.rb"
end
# Implement the required interface for Rails::Generators::Migration.
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
def self.next_migration_number(dirname)
if ActiveRecord::Base.timestamped_migrations
Time.now.utc.strftime("%Y%m%d%H%M%S")
else
"%.3d" % (current_migration_number(dirname) + 1)
end
end
def create_migration
migration_template 'migration.rb', "db/migrate/create_my_zipcode_gem_models.rb"
end
def create_rakefile
template 'zipcodes.rake', "lib/tasks/zipcodes.rake"
end
end
end
# /Users/cblackburn/.rvm/gems/ruby-1.9.2-p136/gems/activerecord-3.0.3/lib/rails/generators/active_record/
It looks like it is calling the migration using parameters that are no longer expected. You have two options:
1) fork the code, update it to use rails 4 conventions, and create a pull request on github. Assuming the owner is still active they will bring your code into the master and republish the gem. You would have help support the community and feel good about it in the process. There are plenty on here like myself who can help you with this.
2) Find another gem to do what you want, such as http://www.rubygeocoder.com/ which I've used several times and is awesome at doing location/zipcode problems

Override Ruby class method; can't resolve namespace

I want to override this method, abbreviated here.
class Redis
module Connection
class Ruby
include Redis::Connection::CommandHelper
def self.connect(config)
if config[:scheme] == "unix"
sock = UNIXSocket.connect(config[:path], config[:timeout])
else
sock = TCPSocket.connect(config[:host], config[:port], config[:timeout])
if config[:scheme] == "rediss" or config[:use_ssl]
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.ca_file = config[:ssl_ca_file]
ssl_context.key = config[:ssl_key]
ssl_context.cert = config[:ssl_cert]
ssl_context.verify_mode = config[:ssl_verify_mode]
ssl_client = OpenSSL::SSL::SSLSocket.new sock, ssl_context
ssl_client.connect
sock = ssl_client
end
end
instance = new(sock)
instance.timeout = config[:timeout]
instance.set_tcp_keepalive config[:tcp_keepalive]
instance
end
end
end
end
So I've created a RubyGem, that has a runtime dependency on 'redis'. In the gem's lib folder, I have a file with
begin
require "openssl"
rescue LoadError
#ignore the error, ssl support will not work
end
Redis::Connection::Ruby.class_eval do
def self.connect(config)
if config[:scheme] == "unix"
sock = UNIXSocket.connect(config[:path], config[:timeout])
else
sock = TCPSocket.connect(config[:host], config[:port], config[:timeout])
if config[:scheme] == "rediss" or config[:use_ssl]
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.ca_file = config[:ssl_ca_file]
ssl_context.key = config[:ssl_key]
ssl_context.cert = config[:ssl_cert]
ssl_context.verify_mode = config[:ssl_verify_mode]
ssl_client = OpenSSL::SSL::SSLSocket.new sock, ssl_context
ssl_client.connect
sock = ssl_client
end
end
instance = new(sock)
instance.timeout = config[:timeout]
instance.set_tcp_keepalive config[:tcp_keepalive]
instance
end
end
Here's the error I get:
/vagrant/misinformed/redis-rb-ssl/lib/redis/connection/ruby.rb:7:in `<top (required)>': uninitialized constant Redis::Connection::Ruby (NameError)
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis/connection.rb:9:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis/connection.rb:9:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis.rb:2631:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis.rb:2631:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:76:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:72:in `each'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:72:in `block in require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:61:in `each'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:61:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler.rb:134:in `require'
from /vagrant/dragondoor/config/application.rb:7:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:146:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:146:in `require_application_and_environment!'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:68:in `console'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:8:in `require'
from bin/rails:8:in `<main>'
How can I override that method? My guess is that I either have the namespacing wrong or I need to require something, but I haven't been able to get anything to work.
UPDATED:
Per a deleted comment, I also tried
begin
require "openssl"
rescue LoadError
#ignore the error, ssl support will not work
end
class Redis
module Connection
Ruby.class_evel do
def self.connect(config)
if config[:scheme] == "unix"
sock = UNIXSocket.connect(config[:path], config[:timeout])
else
sock = TCPSocket.connect(config[:host], config[:port], config[:timeout])
if config[:scheme] == "rediss" or config[:use_ssl]
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.ca_file = config[:ssl_ca_file]
ssl_context.key = config[:ssl_key]
ssl_context.cert = config[:ssl_cert]
ssl_context.verify_mode = config[:ssl_verify_mode]
ssl_client = OpenSSL::SSL::SSLSocket.new sock, ssl_context
ssl_client.connect
sock = ssl_client
end
end
instance = new(sock)
instance.timeout = config[:timeout]
instance.set_tcp_keepalive config[:tcp_keepalive]
instance
end
end
end
end
which seems to have gotten me a little farther, but still getting an error message
/home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.2.0/lib/rails/app_rails_loader.rb:39: warning: Insecure world writable dir /vagrant/dragondoor in PATH, mode 040777
/home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler.rb:302: warning: Insecure world writable dir /vagrant/dragondoor in PATH, mode 040777
/vagrant/misinformed/redis-rb-ssl/lib/redis/connection/ruby.rb:9:in `<module:Connection>': uninitialized constant Redis::Connection::Ruby (NameError)
from /vagrant/misinformed/redis-rb-ssl/lib/redis/connection/ruby.rb:8:in `<class:Redis>'
from /vagrant/misinformed/redis-rb-ssl/lib/redis/connection/ruby.rb:7:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis/connection.rb:9:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis/connection.rb:9:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis.rb:2631:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/redis-3.2.1/lib/redis.rb:2631:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:76:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:72:in `each'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:72:in `block in require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:61:in `each'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler/runtime.rb:61:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/bundler-1.7.12/lib/bundler.rb:134:in `require'
from /vagrant/dragondoor/config/application.rb:7:in `<top (required)>'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:146:in `require'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:146:in `require_application_and_environment!'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:68:in `console'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/vagrant/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-4.1.9/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:8:in `require'
from bin/rails:8:in `<main>'
Try adding require 'redis' to the file where you monkey patch the method:
require 'redis'
class Redis
module Connection
class Ruby
def self.connect(config)
puts 'the method is overriden'
end
end
end
end

Rails monkey patch only on certain columns

I am trying to include a module only if the subclass has a certain column,
and I am doing this in an initializer:
class ActiveRecord::Base
def self.inherited(subclass)
subclass.include(MultiTenancy) if subclass.new.respond_to?(:tenant_id)
end
end
I keep getting this error:
NoMethodError: undefined method `[]' for nil:NilClass
Here is the module that I am importing:
module MultiTenancy
class TenantNotSetError < StandardError ; end
def self.included(model)
model.class_eval do
belongs_to :tenant
validates :tenant_id, presence: true
default_scope -> {
raise TenantNotSetError.new unless Tenant.current_tenant
where(tenant_id: Tenant.current_tenant.id)
}
def multi_tenanted?
true
end
end
end
end
What am I doing wrong. I can include the module on any subclass separate eg. Klass.include(MultiTenancy) successfully, so the problem is with the initializer.
Below is the stack trace:
from -e:1:in `<main>'2.1.1 :002 > Klass.all
NoMethodError: undefined method `[]' for nil:NilClass
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:9:in `relation_delegate_class'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:112:in `relation_class_for'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:106:in `create'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/model_schema.rb:133:in `table_name='
from /home/lee/Code/mobifit/app/models/klass.rb:25:in `<class:Klass>'
from /home/lee/Code/mobifit/app/models/klass.rb:22:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:443:in `load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:443:in `block in load_file'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:633:in `new_constants_in'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:442:in `load_file'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:342:in `require_or_load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:480:in `load_missing_constant'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:180:in `const_missing'
from (irb):2
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:90:in `start'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:9:in `start'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:69:in `console'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands.rb:17:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `block in require'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /home/lee/Code/mobifit/bin/rails:8:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `block in load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /home/lee/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/lee/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from -e:1:in `<main>'2.1.1 :003 >
If you follow the stack trace back a bit, you can see that the thing that's nil that isn't supposed to be is is the class's #relation_delegate_cache. Looking at the source, you can see that this normally gets initialized in the initialize_relation_delegate_cache method, which is called in the inherited hook for ActiveRecord::Delegation::DelegateCache.
ActiveRecord::Base extends this module, so normally a class that inherits from ActiveRecord::Base would call this inherited hook. So the problem with your code is that you're monkey-patching inherited on ActiveRecord::Base, which means that the hook in ActiveRecord::Delegation::DelegateCache is no longer being called.
Two comments:
This is why it's a bad idea to monkey-patch, especially something as fundamental and complex as active record. Is it possible to do what you want to do in a more straightforward way?
If it's not, you should take some notes on how ActiveRecord::Delegation::DelegateCache works and rewrite your monkey patch to mix in a module of your own, rather than just over-writing ActiveRecord::Base's inherited method.
The suggestion in (2) would look something like this:
module MultitenancyConcern
def self.inherited(subclass)
subclass.include(MultiTenancy) if subclass.column_names.include?("tenant_id")
super #this is critical for avoiding the error you're getting
end
end
then your monkey-patch becomes just
ActiveRecord::Base.extend(MultitenancyConcern)

RSpec let method not generating variable

I'm trying to create a test for my bill_total helper method. The let method isn't generating the bill1 and bill2 variable.
describe BillsHelper do
let(:bill1) { Bill.create(name: 'Bill 1', amount: 1.00) }
let(:bill2) { Bill.create(name: 'Bill 2', amount: 1.00) }
describe "#bill_total" do
bill1.amount = 1.00
bill2.amount = 1.00
expect(bills_helper.bill_total).to eq(2.00)
end
end
Error:
/Users/adrianleeelder/Documents/Developer_Resources/sites/bills_app/spec/helpers/bills_helper_spec.rb:18:in `block (2 levels) in <top (required)>': undefined local variable or method `bill1' for #<Class:0x007fb3c121b548> (NameError)
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:242:in `module_eval'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:242:in `subclass'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:228:in `describe'
from /Users/adrianleeelder/Documents/Developer_Resources/sites/bills_app/spec/helpers/bills_helper_spec.rb:17:in `block in <top (required)>'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:242:in `module_eval'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:242:in `subclass'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:228:in `describe'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/dsl.rb:18:in `describe'
from /Users/adrianleeelder/Documents/Developer_Resources/sites/bills_app/spec/helpers/bills_helper_spec.rb:13:in `<top (required)>'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `load'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `block in load_spec_files'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `each'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `load_spec_files'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:22:in `run'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:80:in `run'
from /Users/adrianleeelder/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:17:in `block in autorun'
[Finished in 2.4s with exit code 1]
The names defined in let statements are only available within before and it blocks, not within the outer level of the describe blocks. If you replace your inner describe with it, the names will be accessible. Also, the names are not actually variables, but helper methods.
You need to write your examples inside it blocks, not describe blocks:
it "#bill_total" do
bill1.amount = 1.00
bill2.amount = 1.00
expect(bills_helper.bill_total).to eq(2.00)
end

Resources