ruby - Rails API 类方法加载的奇怪行为
问题描述
项目设置:我正在运行与 Mongoid 链接到 MongoDb 4.4.1 的 Rails 6.0.3.4 / Ruby 7.1.2 API,并获得了一个控制器,例如:
module Api
module V1
class ApplicationController < ActionController::Base
include Concerns::Api::Structuralizers::Collectionable
include Concerns::Api::Structuralizers::Instanceable
include Concerns::Api::Structuralizers::Showable
include Concerns::Api::Structuralizers::Mutable
include Concerns::Api::Structuralizers::Creatable
include Concerns::Api::Structuralizers::Updatable
include Concerns::Api::Structuralizers::Destroyable
before_action :set_instance, only: %i[show edit update destroy]
skip_before_action :verify_authenticity_token
@@model_module = nil
def initialize
super
@model_name = (@@model_module ? "#{@@model_module}::" : '') + controller_name.classify
begin
if @model_name && @model_name != 'Application'
@model = @model_name.constantize
@serializer = "#{@model_name}Serializer".constantize
end
rescue NameError => e
Rails.logger.warn "TEST was unable to process model or serializer #{e}"
end
@acceptable_params = @regex_params = @regex_default_params = @regex_params = @valid_operators = []
end
class << self
def model_module(model_module_name = nil)
return @@model_module if !model_module_name
@@model_module = model_module_name
end
end
end
end
然后这个继承行为的人:
module Api
module V1
class RunesController < ApplicationController
model_module 'LanguageConcepts'
include Concerns::Api::CommonControls
end
end
end
关注的是基本的 CRUD 集成。
我得到了这种非常奇怪和令人沮丧的行为:
启动时:
导轨
当我在索引路径上调用 GET 方法时,我得到了这个:
Api::V1::RunesController:Class 的未定义方法“model_module”
虽然使用控制台
导轨 c
Api::V1::RunesController.model_module
我得到:
《语言概念》
然后,如果我将方法类声明更改为:
def self.model_module[...]
并且保存,大多数时候问题会自行解决。然后过了一会儿(我可以说是随机的时间),它又回到了被窃听的状态,我需要再次编辑 ApplicationController 以将其反转到以前的状态。当它再次发生时,我需要向后做同样的事情,令人作呕......
我真的不明白发生了什么。任何人的想法?
解决方案
我只会使用类实例变量:
module Api
module V1
class ApplicationController < ActionController::Base
include Concerns::Api::Structuralizers::Collectionable
include Concerns::Api::Structuralizers::Instanceable
include Concerns::Api::Structuralizers::Showable
include Concerns::Api::Structuralizers::Mutable
include Concerns::Api::Structuralizers::Creatable
include Concerns::Api::Structuralizers::Updatable
include Concerns::Api::Structuralizers::Destroyable
before_action :set_instance, only: %i[show edit update destroy]
skip_before_action :verify_authenticity_token
@model_module = nil
def initialize
super
@model_name = (class.model_module ? "#{class.model_module}::" : '') + controller_name.classify
begin
if @model_name && @model_name != 'Application'
@model = @model_name.constantize
@serializer = "#{@model_name}Serializer".constantize
end
rescue NameError => e
Rails.logger.warn "TEST was unable to process model or serializer #{e}"
end
@acceptable_params = @regex_params = @regex_default_params = @regex_params = @valid_operators = []
end
class << self
attr_accessor :model_module
end
end
end
在类主体中声明一个实例变量,就是在单例类的范围内声明它。结果就像一个类变量,但线程安全且不在类及其子类之间共享。使用attr_accessor :model_module
insideclass << self
声明了一个类级别的 setter/getter。
而不是“宏方法”,只需使用 setter/getter,因为它实际上并没有做任何非凡的事情:
module Api
module V1
class RunesController < ApplicationController
self.model_module = 'LanguageConcepts'
include Concerns::Api::CommonControls
end
end
end
此代码不需要读者查找 的定义model_module
以查看发生了什么。我们可以立即看到我们正在分配一些东西。
推荐阅读
- sql-server - 在没有聚合函数的 SQL Server 中使用 PIVOT
- r - r中带有plm和coeftest的二元运算符错误的非数字参数
- json - 如何从数据帧列中的路径读取 AWS 上 pyspark 中的许多 Json 文件?
- powershell - 在 PS 中循环回到脚本的开头
- hive - HUE 工作流程失败:主类 [org.apache.oozie.action.hadoop.Hive2Main],退出代码 [2]
- python - 根据其他列值的存在删除重复行
- c# - 每个不为空的 Parameter 对象属性,作为条件添加到表达式谓词中
- react-native - 如何在 React Native 中对平面列表进行排序?
- html - tinymce 在博客中有双文本框
- javascript - 检查管理员是否登录然后才创建特殊按钮的安全方法?