【问题标题】:Override a Mongoid model's setters and getters覆盖 Mongoid 模型的 setter 和 getter
【发布时间】:2011-09-05 09:59:53
【问题描述】:

有没有办法覆盖 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 方法在哪里可以在不使用虚拟字段的情况下被覆盖?

【问题讨论】:

标签: ruby mongoid


【解决方案1】:

更好的使用

def name=(projectname)
  super(projectname.capitalize)
end

方法

self[:name] = projectname.capitalize

可能很危险,导致过载会导致无限递归

【讨论】:

【解决方案2】:
def name=(projectname)
  self[:name] = projectname.capitalize
end

【讨论】:

  • @user923636 您无法更改文档的“_id”字段一旦创建。因此,如果项目名称发生更改,您将不得不删除旧文档并创建一个更改名称的新文档。
【解决方案3】:

我有一个类似的问题,需要为 belongs_to :user 关系覆盖“用户”设置器。我想出了这个解决方案,不仅是为了这种情况,而且是为了包装同一个类中已经定义的任何方法。

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

【讨论】:

  • 正是我想要的,而且很好的解决方案。 +1
  • 不要试图改造自行车。为此使用 alias_method_chain。
  • 谢谢!与关系设置者和获取者也有问题。 sandrew 的评论让我研究了 a_m_c,我了解了 Ruby 2.0 的 Module#prepend。很棒的解决方案,非常干净 - dev.af83.com/2012/10/19/ruby-2-0-module-prepend.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
  • 2011-03-11
  • 2014-08-05
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
相关资源
最近更新 更多