In a rails application
- We have model
PointTransaction
inside modulePs
module Ps
class PointTransaction
...
end
end
- We have an api controller
Api::V1::Ps::DailyLoginsController
class Api::V1::Ps::DailyLoginsController
# I1
def index
@txs = Ps::PointTransaction.all
end
# I2
def index
@txs = ::Ps::PointTransaction.all
end
end
-
I1
-
Parent namepsace as the algorithm here, we have
Api::V1::Ps::DailyLoginsController
Api::V1::Ps
Api::V1
Api
top namespace
-
Resolve
Ps::PointTransaction
processes by this procedure follows the above parent namespaces in order:-
First run
Api::V1::Ps::DailyLoginsController
Cannot foundapi/v1/ps/daily_logins_controller/ps.rb
Cannot foundapi/v1/ps/daily_logins_controller/ps
Ps
is existed on the parentApi::V1::Ps
=> raise NameError`
Following the logicIf none of the parent namespaces of the class or module has the missing constant then Rails assumes the reference is relative. Otherwise qualified.
That above logics force
Ps
must be defined on direct parent namespaceApi::V1::Ps::DailyLoginsController
=> Finally the NameError is:uninitialized constant Api::V1::Ps::DailyLoginsController::Ps
-
-
Solution
- Use top namespace ::Ps::PointTransaction
- Make
Ps
load first out side the moduel. E.gsputs Ps
- Use
require_dependency
- Change module controller different from model or otherwise
Api::V1::Ps::DailyLoginsController
toApi::V1::Cs::DailyLoginsController
ORPs::PointTransaction
toCs::PointTransaction
-
-
I2
::Ps::PointTransaction.all
will forcePs
was found ontop namesapce
=> It'll run fine
- Load Top namespace
User
before
puts User
module Admin
class UsersController
puts Admin::User
end
end
Bonus Api::V1::Ps::DailyLoginsController
was defined (also as the procedure)
-
Find
Api
-
Find
Api::V1
-
Find
Api::V1::Ps
-
Find
Api::V1::Ps::DailyLoginsController
-
Normal load
module Admin
class UsersController
puts Admin::User
end
end
- 1 will get error because when
puts Admin::User
execute, User's already existed.User
here is a quanlified references => force find user in admin/user.rb as describe here - 2 will run as normal because when
puts Admin::User
run,User
constant is still not existed, Rails will considerUser
as relative refernece => load top namespaceUser
. - Note: This above is only true when these code run only (run first)