如何通过模块巧妙覆盖ruby-on-rails中的attr_accessor getter方法?

2026-04-11 16:422阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计402个文字,预计阅读时间需要2分钟。

如何通过模块巧妙覆盖ruby-on-rails中的attr_accessor getter方法?

rubyclass HasUrl extend ActiveSupport::Concern

included do attr_accessor :bar end

def bar 0 endend

class Foo

bar属性不会存储在数据库中,但可以以表单单行形式使用(如使用SimpleForm的f.input)。

module HasUrl extend ActiveSupport::Concern included do attr_accessor :bar end def bar 0 end end class Foo < ActiveRecord::Base include HasUrl end

bar属性不存储在数据库中,但它以表单形式使用(使用SimpleForm的f.input).我想覆盖此方法的getter,因此我可以根据其他属性设置bar并使表单正确预填充值.

问题是在这样的包含块中使用attr_accessor将在Foo类上设置getter.因为模块包含在祖先链中的Foo上方,所以永远不会触及返回0的自定义bar方法.

解决这个问题的一种方法是

class Foo < ActiveRecord::Base include HasUrl def bar super end end

但我想避免这一额外的步骤.我只是想要包含该模块,让它只是“工作”.另一种选择是在我的表单中使用不同的帮助器(f.input_field等)但是我不能利用SimpleForm的包装器.

模块#prepend也不能解决我的问题,因为HasUrl还定义了一些其他的东西(特别是ActiveRecord回调).如果我在前面,这些回调会导致错误:

NoMethodError: undefined method `_run_...__find__...__callbacks`

有没有办法解决这个错误,以便prepend可以工作?或者另外一种方法呢?

你确定要的是attr_accessor吗? attr_writer不会足够吗?

require 'active_support/all' module HasUrl extend ActiveSupport::Concern included do attr_writer :bar end def bar 0 end end class Foo include HasUrl end p Foo.new.bar

无论如何,如果你真的想使用attr_accessor,这应该工作:

如何通过模块巧妙覆盖ruby-on-rails中的attr_accessor getter方法?

require 'active_support/all' module HasUrl extend ActiveSupport::Concern included do attr_accessor :bar define_method :bar do 0 end end end class Foo include HasUrl end p Foo.new.bar

本文共计402个文字,预计阅读时间需要2分钟。

如何通过模块巧妙覆盖ruby-on-rails中的attr_accessor getter方法?

rubyclass HasUrl extend ActiveSupport::Concern

included do attr_accessor :bar end

def bar 0 endend

class Foo

bar属性不会存储在数据库中,但可以以表单单行形式使用(如使用SimpleForm的f.input)。

module HasUrl extend ActiveSupport::Concern included do attr_accessor :bar end def bar 0 end end class Foo < ActiveRecord::Base include HasUrl end

bar属性不存储在数据库中,但它以表单形式使用(使用SimpleForm的f.input).我想覆盖此方法的getter,因此我可以根据其他属性设置bar并使表单正确预填充值.

问题是在这样的包含块中使用attr_accessor将在Foo类上设置getter.因为模块包含在祖先链中的Foo上方,所以永远不会触及返回0的自定义bar方法.

解决这个问题的一种方法是

class Foo < ActiveRecord::Base include HasUrl def bar super end end

但我想避免这一额外的步骤.我只是想要包含该模块,让它只是“工作”.另一种选择是在我的表单中使用不同的帮助器(f.input_field等)但是我不能利用SimpleForm的包装器.

模块#prepend也不能解决我的问题,因为HasUrl还定义了一些其他的东西(特别是ActiveRecord回调).如果我在前面,这些回调会导致错误:

NoMethodError: undefined method `_run_...__find__...__callbacks`

有没有办法解决这个错误,以便prepend可以工作?或者另外一种方法呢?

你确定要的是attr_accessor吗? attr_writer不会足够吗?

require 'active_support/all' module HasUrl extend ActiveSupport::Concern included do attr_writer :bar end def bar 0 end end class Foo include HasUrl end p Foo.new.bar

无论如何,如果你真的想使用attr_accessor,这应该工作:

如何通过模块巧妙覆盖ruby-on-rails中的attr_accessor getter方法?

require 'active_support/all' module HasUrl extend ActiveSupport::Concern included do attr_accessor :bar define_method :bar do 0 end end end class Foo include HasUrl end p Foo.new.bar