Ruby 覆盖Mongoid模型';s二传手和接球手

Ruby 覆盖Mongoid模型';s二传手和接球手,ruby,mongoid,Ruby,Mongoid,有没有办法覆盖Mongoid中模型的setter或getter?比如: class Project include Mongoid::Document field :name, :type => String field :num_users, type: Integer, default: 0 key :name has_and_belongs_to_many :users, class_name: "User", inverse_of: :projects #

有没有办法覆盖Mongoid中模型的setter或getter?比如:

class Project
  include Mongoid::Document
  field :name, :type => String
  field :num_users, type: Integer, default: 0
  key :name
  has_and_belongs_to_many :users, class_name: "User", inverse_of: :projects

  # This will not work
  def name=(projectname)
    @name = projectname.capitalize
  end
end
如果不使用虚拟字段就可以覆盖
name
方法?

更好地使用

def name=(projectname)
  self[:name] = projectname.capitalize
end
def name=(projectname)
  super(projectname.capitalize)
end
方法

self[:name] = projectname.capitalize

可能是危险的,因为重载它会导致无休止的递归

我也遇到过类似的问题,需要覆盖“用户”setter以建立一个属于:用户关系。我提出这个解决方案不仅是为了解决这个问题,而且是为了包装在同一个类中已经定义的任何方法

class Class  
  def wrap_method(name, &block)
    existing = self.instance_method(name)

    define_method name do |*args|
      instance_exec(*args, existing ? existing.bind(self) : nil, &block)
    end
end
这允许您在模型类中执行以下操作:

wrap_method :user= do |value, wrapped|
    wrapped.call(value)
    #additional logic here
end

相关:@user923636一旦创建文档,就不能更改文档的“\u id”字段。因此,如果项目名称发生更改,您将不得不删除旧文档并创建一个名称发生更改的新文档。@GearHead我也已切换到super over timme(它看起来更好),尽管我的部分代码仍然使用self[:name]表示法,并且到目前为止还没有遇到任何递归。如果没有super类,
super
如何工作
Mongoid::Document
是作为模块包含的,我在这里很困惑…@tothemario看看,我到底在寻找什么,很好的解决方案+1不要试图改造自行车。使用别名\u方法\u链进行此操作。谢谢!在人际关系建立者和获得者方面也有困难。sandrew的评论让我研究了a_m_c,我了解了Ruby 2.0的模块prepend。很好的解决方案,而且非常干净-