Ruby 覆盖Mongoid模型';s二传手和接球手
有没有办法覆盖Mongoid中模型的setter或getter?比如: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 #
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。很好的解决方案,而且非常干净-