Circular dependency detected while autoloading a constant - ruby

I upgraded Rails from version 3.1.2 (which worked fine) to 4.0, and got stuck with the following error:
circular dependency detected while autoloading constant Foo
I created a class ProductFactory, where I instantiate different models. For example:
p = Foo.new(params)
The model "Foo" is not always an ActiveRecord. Could anyone help me with this issue?

Best I'm aware, circular dependencies error messages usually occur when cascading includes go wrong by recursively requiring a file before it is fully loaded, e.g.:
# File A:
require 'B'
module Foo; end
# File B:
require 'A'
module Foo; end
Any odds this is the kind of situation you're ending up with?

I had this error because I manually renamed controllers, routes etc etc and forgot to rename it in the first line of the files.
Was named
class AController < ApplicationController
instead of
class ARenamedController < ApplicationController
and I had gone and renamed all the other files individuall.
Not best practice I know, but I am learning and figuring it out, and in this case created the error this person is talking about. So if you got here through Google like I did, there is my solution.

This kind of issues often happen when you change the version of Rails. You maybe didnt update the gems on the right order.

Related

NameError: uninitialized constant #<Class:0x00007fadd32ea580>::Searchable

While debugging an unrelated issue in rspec, I'm coming across issues with constant loading.
The setup is as follows:
# app/models/foo.rb
class Foo << ApplicationRecord
include Foo::Searchable
end
# app/models/foo/searchable.rb
module Foo::Searchable
extend ActiveSupport::Concern
included do
#yada yada
end
end
I received the following error while debugging. NameError: uninitialized constant #<Class:0x00007fadd32ea580>::Searchable
Changing the naming to Foos::Searchable with corresponding folder move does fix the issue but I would like to understand what is actually happening.
Rails 6.0.3.1 Ruby 2.6.6
As well as using << instead of < you have fallen victim to really common issue due to missusing the scope resolution operator ::. It should not be used when declaring nested classes or modules as it leads to the wrong module nesting and will lead to a missing constant error unless the module which you are nesting in is already loaded.
You should always explitly declare nested modules/classes:
class Foo < ApplicationRecord
module Searchable
extend ActiveSupport::Concern
included do
#yada yada
end
end
end
The reason this issue is popping up everywhere after the transition to Rails 6 is that the old classic autoloader overloaded Module#const_missing and glassed over these bugs as it would autoload Foo.
Zeitwork which replaces the classic autoloader instead uses Module#autoload which is a relatively new addition to Ruby and a lot less hacky.
This turns out to be caused by incompatibility with Byebug. Byebug stops the events Zeitwerk uses for autoloading to fire off in a debugging session. The issue is described here.
The << was a typo and would not result in that error.
Perhaps you should replace << with <. You inherit, not redirect
class Foo < ApplicationRecord
include Foo::Searchable
end

Using Test::Unit::Data

I am trying to create some data driven API tests using Test::Unit for ruby. The eventual intention is to read a series of test cases in from a .csv file. In looking for something that would be the equivalent of #dataprovider for testng, I found a class called Data which looks like exactly what I need.
http://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/Data/ClassMethods
However, when I tried to create a test case to try to get it working, I get an error saying
"initial_test.rb:4:in <class:InitialTest>': undefined methoddata' for InitialTest:Class (NoMethodError)
"
code I was running:
require "test/unit"
class InitialTest < Test::Unit::TestCase
data("true" => [true],
"false" => [false])
def test_true_is_true(data)
value = data
assert(false, "FAIL!")
end
end
I can't seem to find any mention of the Data class outside of the documentation. Has anyone used this class? Am I missing something?
I'm not familiar with this module in particular, but since data is defined as an instance method on Test::Unit::Data and Test::Unit::Data is a Module, this works:
class YourTest < Test::Unit::TestCase
include Test::Unit::Data
data(…)
end
This said, you're going to want to take a closer look at the docs you linked since your example usage is looking like copy-pasta.
Turns out that the problem was that I was using an older version of Ruby that did not include the class I was trying to use. Updating to a newer version solved the problem.

ruby/rails module based namespacing failure

I'm experiencing a failure to understand how Ruby module based namespacing is supposed to work. I've always understood it to be that if you have two classes with the same name you can put one in a module to clarify namespace.
At the moment this doesn't work and I can't see why. In app/models/something/baz.rb I have:
class Baz < ActiveRecord::Base
self.table_name = 'baz'
end
I'm not sure why the table_name assignment is in there. Perhaps because of the fact that this file is nested under something?
In lib/foo/bar/baz.rb I have:
module Foo
module Bar
class Baz
end
end
end
I've included, in order, the paths lib/foo, lib/bar in my autoload_paths config value in config/application.rb:
config.autoload_paths += %W(
#{config.root}/lib
#{config.root}/lib/import
#{config.root}/lib/foo
#{config.root}/lib/foo/bar
#{config.root}/app/models/concerns
#{config.root}/app/services
#{config.root}/app/controllers/concerns
#{config.root}/app
)
at the console I can successfully reference the Foo, Foo::Bar modules but when I try to do Foo::Bar::Baz I get the usual error
expected Baz to be defined in lib/foo/bar/baz.rb
now I change that class to be in lib/foo/bar/baz_thing.rb and refer to it in console as Foo::Bar::BazThing everything works. I've come to the possibly erroneous conclusion that the autoload implementation is mightly confused because there are two classes with the same name.
I've double, triple and quadruple checked names and paths on all of this.
I also read through all the suggested possible alternative/duplicate questions shown when creating this ticket and could find none that addressed my situation closely enough to answer my question.
Can anyone identify where I've gone wrong and why my expectations on module namespacing behavior are incorrect?
This is on ruby 2.2.2 and Rails 4.2.6

A copy of MyModel has been removed from the module tree but is still active

Whenever I change any code (except views and perhaps some controllers) I get:
A copy of MyModel has been removed from the module tree but is still
active!
and I have to restart my dev server.
I have combed the interwebs on this issue, and the most commonly stated root cause is calling MyModel.some_method from some class that is not autoloaded. I have classes in lib that call like MyModel.find and MyModel.some_scope; however, I have configured Rails to autoload every file in the lib tree. I went so far as to configure autoloading of everything, including every file anywhere under app and even config.
One fact that might be relevant is that MyModel is the base of an STI hierarchy. It has two children, and one those has a child.
This is driving me nuts, because I have no more ideas for how to troubleshoot it. Meanwhile, productivity has gone to hell.
How can I find the source of this?
It means your app still has references to the old version. I think it should be visible from the stack trace exactly where it is getting referenced.
Also, don't add lib to autoload, if it was meant to be autoloaded it would be. I don't know what this model is but possibly you should put it into app/services or app/models (no matter if it's ActiveRecord or not).
I ran into the same issue. Basically, it is caused by old references when Rails is trying to reload, most likely happen to nested modules/classes like below:
module A
def self.b
B
end
end
class C
def d
#d ||= D.new
end
end
You need to update it to:
module A
def self.b
self::B # or A::B
end
end
class C
def d
#d ||= C::D.new
end
end
So in your case, every module/class NestedModuleOrClass under MyModel will need to update to MyModel::NestedModuleOrClass.
Try this and let me know if it works for you or not.

Where and how should I add this new 'non-rails-way' method in my Rails application

I've written a small method to query and retrieve from an MS SQL 2008 server and I am not sure where to put the code in my rails app.
The scenario:
I am writing a Ruby and Rails app with a connection to a legacy MS SQL 2008 server DB.
A lot is working as expected, which is nice.
For now I work off a copy of the legacy DB and I treat it as readonly. It's big (7000+ tables some of which have over 40 million records). I am using it 'as-is' and don't want to change any of the underlying schema.
I do want to extend some very server-specific functionality. For instance, I make use of:
thing = ActiveRecord::Base.connection.exec_query(my_query_string_here)
... and it works. The result is an array that contains a hash and I can get to the relevant hash value by using:
thing[0][""]
... which works.
So, I thought I should write a method to make this easier and I wrote:
Class Tool < ActiveRecord::Base
def self.queryRDW(x)
res=ActiveRecord::Base.connection.exec_query(x)
ret=res.to_hash
return ret[0][""]
end
end
and put it in config/initializers/tool.rb Unfortunately, webrick complains about the file during boot with the following cryptic error:
.../config/initializers/tool.rb:7: syntax error, unexpected keyword_end, expecting $end (SyntaxError)
I recognize that this is not an out-of-the-box rails-way of doing things, so please don't remind me. (My struggles remind me often enough)
My question:
Where should I put this code so that I can invoke it from within a controller or a view in my rails app? Does this need to be a new Class method or something else?
Many thanks!
Addendum:
I changed Class to class (doh!)
I moved tool.rb into lib/
I changed tool.rb to now be:
module Tool
def self.queryRDW(x)
res = ActiveRecord::Base.connection.exec_query(x)
res.to_hash[0][""]
end
end
but doing this in app/views/stats.html.erb
thing=queryRDW("mysql string")
gets me an 'undefined method error'
Addendum 2
I made the directory app/concerns and put tool.rb there.
When I use:
<%=queryRDW("myStringHere")%>
in:
app/views/stats.html.erb
I get:
undefined method `queryRDW' for #<#<Class:0x0000000378ccf8>:0x00000003c1ce58>
You need to lowercase the keyword class in line 1.
I'd also say that this class doesn't need to inherit from ActiveRecord::Base — and doesn't even really need to be a class — if it's simply a wrapper around exec_query. There's nothing "wrong" with this, but if you never intend to instantiate an object of this class, you could just create a simple utility module:
module Tool
def self.queryRDW(x)
res = ActiveRecord::Base.connection.exec_query(x)
res.to_hash[0][""]
end
end
You can save this file in a couple of places:
lib/tool.rb. If you're using Rails 3, you'll need to add (or uncomment) this line in config/application.rb:
# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
app/concerns/tool.rb. This will automatically be detected by Rails 3.
I generally use app/concerns for tools that are entirely application-specific and lib for utilities that I might reuse among several different applications.
I wouldn't put this in config/initializers. This seems like code you'd put in app/models.
The error you're getting is syntax related, so double check the syntax.
To answer your question more directly, though, it's acceptable to put this stuff in your model if it's model related (in other words, part of your business domain). If it is something extraneous or orthogonal to your domain, I'd put it in lib.
Hope this helps.

Resources