Module and Class with the Same Name in Rails Project

How do I use a model that has the same name as a gem?

You can't. A module and class of the same name cannot exist at the top-level namespace. If you actually did get Rails to load your Stripe module, your app would crash with a type error, complaining that you've tried to change the type of Stripe from module to class.

ruby modules and classes same name in structure

Bar can't be a module and a class, they are different things.

Change bar.rb to module Bar or change other_bar.rb to class Bar.

Whichever it is, it has to be consistent. You can't change one to the other. The question is which should it be? If Bar is a container for other classes and only has a few global singleton methods? Then it's a module. But if it can be instantiated, then it's a class.

And yes, you can nest classes. This is totally acceptable:

class Bar
class OtherBar
puts "running module Bar with class OtherBar"
end
end

Bar::OtherBar.new # yay!

Modules and Classes can be nested inside either other in any way you see fit.


Edit with some commented examples to help clear this all up:

module Foo

# Foo::A
class A
# simple namespaced class
end

# Foo::B, inherits from Foo::A
class B < A
# inherting from a class in the same namespace
end

# modify Foo::B
class B
# When modifying an existing class you don't need to define the superclass
# again. It will raise an error if you reopen a class and define a different
# superclass. But leaving it off is fine.
end

# nested module Foo::Inner
module Inner

# Foo::Inner::C
class C
# simple more deeply namespaced class
end

# Foo::Inner::D, inherits from Foo::A
class D < A
# inherits from a class in a parent namespace

# works because ruby looks upward in the nesting chain to find missing constants.
end

# Foo::Inner::Foo
class Foo
# simple nested class with the same name as something in a parent namespace

# This is a totally different Foo, because it's in a different namespace
end

# Foo::Inner::E, inherits from Foo::Inner::Foo
class E < Foo
# class inhereting from another class in the same namespace

# Foo::Inner::Foo is "closer" than the global Foo, so that gets found as the superclass
end

# Foo::Inner::F, which mixes in the gloabl module Foo
class F
# the :: constant prefix says to start looking in the global namespace
# so here we include the top level module Foo, and not the "closer" in namespace Foo::Inner::Foo
include ::Foo

# This is an error. This attempts to include the class Foo::Inner::Foo since thats the closest by namespace
# thing that matches the constant Foo. (you can't include classes, only modules)
# You need the :: prefix to grab the global Foo module
include Foo
end

end
end

# Z decalred in the global namespace, which inherits from the deeply nested class Foo::Inner::C
class Z < Foo::Inner::C
# Any class anywhere can inherit from any other class in any namespace.
# Just drill in!
end

# the following 2 declarations at this point would be identical

# This defines a class deep with in a namespace
class Foo::Inner::Foo::Bar < Foo::A
end

# same as above, but reopens each namespace
module Foo
module Inner
class Foo
class Bar < ::Foo::A
end
end
end
end

Having a module and class with the same name

I'd do:

::Stat.by_user_id("ID")

Class and Module with the same name - how to choose one or another?

Prefix the class name with :: in the do_something method...

def do_something
...
data = ::Order.all
...
end

Having a module class with the same name as a top level class: 'expected module_classe_file to define top_level class'

I think the best thing to do in your case is to add themodule/category.rb into the lib directory.

  1. Grab the code from category.rb and create a lib/category.rb file.

  2. Then include your module code into your app/models/category.rb

  3. In application.rb be sure to load the lib directory config.autoload_paths << "#{Rails.root}/lib.

    class Category < ActiveRecord::Base
    include Category

I personally would not do it this way though. The naming gets confusing imo. Have you tried namespacing your code?

For example, you could try this too:

  models/
category/
category_something.rb #change the name of the file to something else
category.rb

Then in your category_something.rb

class Category::CategorySomething
#code code code
end

And then that way you can use the code like a module.

Refer to method in module with same name as class

If you don't want to look up the constant relative to the current scope, just use an absolute path:

::Pushover.configure


Related Topics



Leave a reply



Submit