Override a Mongoid model's setters and getters

2020-05-26 11:05发布

Is there a way to override a setter or getter for a model in Mongoid? Something like:

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

where the name method can be overwritten without using virtual fields?

标签: ruby mongoid
3条回答
SAY GOODBYE
2楼-- · 2020-05-26 11:32
def name=(projectname)
  self[:name] = projectname.capitalize
end
查看更多
可以哭但决不认输i
3楼-- · 2020-05-26 11:46

I had a similar issue with needing to override the "user" setter for a belongs_to :user relationship. I came up with this solution for not only this case but for wrapping any method already defined within the same class.

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

This allows you to do the following in your model class:

wrap_method :user= do |value, wrapped|
    wrapped.call(value)
    #additional logic here
end
查看更多
姐就是有狂的资本
4楼-- · 2020-05-26 11:52

better use

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

the method

self[:name] = projectname.capitalize

can be dangerous, cause overloading with it can cause endless recursion

查看更多
登录 后发表回答