Rails: TypeError: wrong argument type Class (expected Module)
Asked Answered
I

2

11

Inside app/models/abc/xyz.rb

module Abc::Xyz
  extend ActiveSupport::Concern
end

Inside app/models/abc.rb

class Abc < ActiveRecord::Base
  include Abc::Xyz 
end

When I try to fetch data from Abc.where(id: id) sometimes it works and sometimes it returns this error(TypeError: wrong argument type Class (expected Module)).

TypeError: wrong argument type Class (expected Module)
      app/models/abc.rb:2:in `include'
      app/models/abc.rb:2:in `<class:Abc>'
      app/models/abc.rb:1:in `<top (required)>'
      activesupport (3.2.17) lib/active_support/dependencies.rb:469:in `load'
      activesupport (3.2.17) lib/active_support/dependencies.rb:469:in `block in load_file'
      activesupport (3.2.17) lib/active_support/dependencies.rb:639:in `new_constants_in'
      activesupport (3.2.17) lib/active_support/dependencies.rb:468:in `load_file'
      activesupport (3.2.17) lib/active_support/dependencies.rb:353:in `require_or_load'
      activesupport (3.2.17) lib/active_support/dependencies.rb:502:in `load_missing_constant'
      activesupport (3.2.17) lib/active_support/dependencies.rb:192:in `block in const_missing'
      activesupport (3.2.17) lib/active_support/dependencies.rb:190:in `each'
      activesupport (3.2.17) lib/active_support/dependencies.rb:190:in `const_missing'
      activesupport (3.2.17) lib/active_support/inflector/methods.rb:230:in `block in constantize'
      activesupport (3.2.17) lib/active_support/inflector/methods.rb:229:in `each'
      activesupport (3.2.17) lib/active_support/inflector/methods.rb:229:in `constantize'
      activesupport (3.2.17) lib/active_support/core_ext/string/inflections.rb:54:in `constantize'
Incognito answered 2/4, 2014 at 21:50 Comment(9)
Can you show full stacktrace ?Varicocele
I want to see (TypeError: wrong argument type Class (expected Module)) in the error stack, that is importantVaricocele
I would try module Xyz instead. Concerns are supposed to be shared among your models, it doesn't make sense to namespace them to an existing class.Scherzo
@depa Yes,, Abc as a module and class are confusing.. to me and Rails too...Varicocele
If you try to do class X ; end class Y include X end ---- The same error you will get..Varicocele
but problem is sometimes it works and sometimes it doesn't.Incognito
I just want to create module xyz inside abc folder. Is it possible to create a xyz module inside abc folder without writing Abc::Xyz ?Incognito
@depa I got your point. But is it possible to fix this issue instead of changing the structure ?Incognito
first change app/modesl/Abc/xyz.rb to become app/modesl/abc/xyz.rbVav
U
16

I think that you will be better off sticking to the Rails conventions regarding concerns:

  1. Use modules for defining your concerns
  2. Place concerns within app/models/concerns

If you want to namespace your concern as in Abc::Xyz then make sure that you place it in the right path: app/models/concerns/abc/xyz.rb.

Another fine point is that

module Abc::Xyz

assumes that the module Abc has already been defined. If it hasn't it will fail. So maybe you are better using

class Abc
  module Xyz
    #...
  end
end 

Note that I used class Abc and not module as your code implied. You can't have both a class and a module with the same name. That could be also why you get the occasional errors. Please see this fine article on Exploring Concerns as well.

Rails try various stuff while (auto)loading constants but you are better off sticking to the conventions. I have seen many cases where the same snippets of code fail in different points in time or in different environments due to the order of definitions/loading/execution of constants.

Unlatch answered 7/5, 2014 at 9:20 Comment(2)
Thank you so much for detailed explanation. I don't have module Abc. I wanted use Abc as namespace. Because my xyz module was inside abc folder.Incognito
@krunalshah did you change your module declaration to "class Abc; Module Xyz ...` as suggested? Because that would fix your problem imho. If yes: please accept the answer, or give feedback.Mender
U
7

This isn't the right answer to the OPs issue, but I think it could help people finding this question when searching for the error message.

For me the problem was that I had a helper defined like this:

module Api
  class MyControllerHelper
  end
end

But Rails expects the helper to be a module not a class, so it should have been like this:

module Api
  module MyControllerHelper
  end
end

Unspoken answered 21/11, 2020 at 20:2 Comment(1)
thanks @knejad, that was exactly the pointer I needed. I made a new helper and forgot to make it a module!Cameroncameroon

© 2022 - 2024 — McMap. All rights reserved.