You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails中Concern定义的attr_accessor无法访问如何解决

问题核心原因

你代码中定义的attr_accessor :foo被放在了控制器类的单例类作用域下,属于类级别属性,仅能在控制器类的上下文调用。而index是控制器的实例方法,运行时上下文是控制器实例,自然无法直接访问类层面的属性。

解决方法

根据你的实际使用场景,可选择以下两种方案:

方案1:保留类级别共享属性(所有控制器实例共享同一个foo值)

如果你的需求是foo值全局统一,所有该控制器的请求都共用同一个值,只需在Concern中新增实例层的方法代理即可:
修改app/controllers/concerns/foobar_concern.rb代码如下:

module FoobarConcern
  extend ActiveSupport::Concern

  included do
    class << self
      attr_accessor :foo
    end
    # 给实例层添加存取方法代理,指向类的同名方法
    delegate :foo, :foo=, to: :class
  end

  class_methods do
    def test_method(bar)
      self.foo = bar
    end
  end
end

修改后你原有控制器index方法中的self.foo、直接调用foo都可以正常获取到值。

方案2:使用实例级别独立属性(不同请求的foo值互不干扰)

如果你的需求是每个请求对应的控制器实例有独立的foo值,将属性定义调整到实例层面即可:
修改app/controllers/concerns/foobar_concern.rb代码如下:

module FoobarConcern
  extend ActiveSupport::Concern

  included do
    # 直接定义实例层面的存取方法
    attr_accessor :foo
  end

  class_methods do
    def test_method(bar)
      # 给所有实例设置默认foo值
      define_method :initialize do |*args|
        super(*args)
        self.foo = bar
      end
    end
  end
end

修改后控制器实例可以直接调用foo相关方法,且不同请求的属性值互相独立,不会串值。

内容的提问来源于stack exchange,提问作者Dean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:48:00