Đây là một giải pháp đơn giản.
Thay đổi:
- Không cần phải kiểm tra sự tồn tại của
USER_KEY
.
- Cố gắng tìm kiếm hằng số trên mô-đun/lớp của người nhận (trong trường hợp của bạn, nó sẽ là bộ điều khiển). Nếu nó tồn tại, sử dụng nó, nếu không sử dụng module mặc định/lớp (xem dưới đây cho những gì mặc định là).
.
module Auth
USER_KEY = "user"
def authorize
user_key = self.class.const_defined?(:USER_KEY) ? self.class::USER_KEY : USER_KEY
user_id = session[user_key]
def
end
Giải thích
Các hành vi bạn đang thấy là không cụ thể cho đường ray, nhưng là do nơi ruby trông cho hằng số nếu không muốn nói một cách rõ ràng scoped qua ::
(những gì tôi gọi là "mặc định" ở trên). Các hằng số được tra cứu bằng cách sử dụng "phạm vi từ vựng của mã hiện đang thực hiện". Điều này có nghĩa là ruby đầu tiên tìm kiếm hằng số trong mô đun (hoặc lớp) của mã thực thi, sau đó chuyển ra ngoài mỗi mô-đun kèm theo liên tiếp (hoặc lớp) cho đến khi nó tìm thấy hằng số được xác định trên phạm vi đó.
Trong bộ điều khiển, bạn gọi authorize
. Nhưng khi authorize
đang thực thi, mã thực hiện hiện tại là Auth
. Vì vậy, đó là nơi các hằng số được nhìn lên. Nếu Auth không có USER_KEY
, nhưng một mô-đun kèm theo có nó, thì mô-đun kèm theo sẽ được sử dụng. Ví dụ:
module Outer
USER_KEY = 'outer_key'
module Auth
# code here can access USER_KEY without specifying "Outer::"
# ...
end
end
Trường hợp đặc biệt là môi trường thực thi cấp cao nhất được coi là thuộc lớp Object
.
USER_KEY = 'top-level-key'
module Auth
# code here can access the top-level USER_KEY (which is actually Object::USER_KEY)
# ...
end
Một cái bẫy được xác định một mô-đun hoặc lớp học với các nhà điều hành Phạm vi (::
):
module Outer
USER_KEY = 'outer_key'
end
module Outer::Auth
# methods here won't be able to use USER_KEY,
# because Outer isn't lexically enclosing Auth.
# ...
end
Lưu ý rằng hằng số có thể được định nghĩa nhiều muộn hơn phương pháp được định nghĩa. Tra cứu chỉ xảy ra khi USER_KEY được truy cập, vì vậy công trình này quá:
module Auth
# don't define USER_KEY yet
# ...
end
# you can't call authorize here or you'll get an uninitialized constant error
Auth::USER_KEY = 'user'
# now you can call authorize.
Cảm ơn James, đó là chính xác những gì tôi đang tìm kiếm. – user204078