Trần Kim Dự
Trần Kim Dự

Reputation: 6102

Rails: when do we must put :: before some classes for rails understand base class

In Ruby, I understand that ::ClassName for calling class at base module. For example, here is my code:

module HHT
  module V1
    module OfflineCheckIn
      class PutOfflineCheckInProductsApi < ApplicationApi
        put 'offline' do
          ActiveRecord::Base.transaction do
            OfflineCheckIn.create(check_in_param) # exception here
          end
        end
      end
    end
  end
end

When I run, I meet exception:

NoMethodError (undefined method `create' for HHT::V1::OfflineCheckIn:Module)

As I understand, Rails understand that OfflineCheckIn currently inside module HHT::V1::OfflineCheckIn, so I must call at base class ::OfflineCheckIn. Thing that I don't understand is: at another controller, some previous programmer implements same way with me, but he doesn't need to call :: before model.

So my question is: when we don't need to use :: before class and rails can understand that is base class ?

Thanks

Upvotes: 3

Views: 2180

Answers (1)

Vasfed
Vasfed

Reputation: 18464

You have to call class as ::ClassName if in your hierarchy there's a class/module with the same name, to differentiate between them, for example:

class Foo; end

module Bar
  class Foo; end # this is another Foo

  def self.a
    puts ::Foo == Foo
  end
end

module FooBar
  def self.a
    puts ::Foo == Foo
  end
end

Bar.a # => false
FooBar.a # => true

Here we have ::Foo and ::Bar::Foo, but shorthand Foo points to one of them depending on context.

Also it does not matter if the entities are classes or modules, both are just assigned as a value for a constant:

module Foo; end

module Bar
  Foo = "a string"

  def self.baz
    puts Foo.class
  end
end

puts Foo.class # => Module
Bar.baz # => String

Upvotes: 9

Related Questions