MongoMapper的只读属性/键

时间:2012-02-05 00:14:08

标签: ruby mongodb mongomapper

我想知道是否还有一个属性键只读。这意味着它只能在创建对象时分配

UPDATE :我希望能够使用类似update_attributes的东西,并确保该方法只更新可以覆盖的密钥。例如,如果我有

class User 
    include MongoMapper::Document

    key :firstName, String, :required => true
    key :lastName,  String, :required => true
    key :username,  String, :required => true, :unique => true, :readonly => true
    key :password,  String, :required => true

end

(只读验证是伪代码,我希望存在这样的东西)

然后我希望以下代码引发错误或失败

user = User.find_by_username("foo")
user.update_attributes({:username => "bar"})
puts "You cannot change the username" unless user.valid?

我也想要这样的东西,但这是一个单独的东西

user.update_attributes({:unwantedKey => "fail!"})
puts "You cannot add keys that are not in the User scheme" unless user.valid?

2 个答案:

答案 0 :(得分:1)

我会重新考虑您需要使用验证而不是使用自定义控制器过滤或attr_accessible来控制accessibilty

如果验证确实是正确的解决方案,那么像three suggests那样滚动自己是一个好主意,这里有一些身份映射安全的代码来检查数据库:

validate :username_unchanged, :only_existing_keys, :on => :update

def db_version
  # drop to the driver to get around the identity map
  # (identity map is off by default)
  collection.find_one(:_id => self.id)
end

def username_unchanged
  unless username == db_version['username']
    errors.add(:username, 'cannot be changed')
  end
end

def only_existing_keys
  extra_keys = to_mongo.keys - db_version.keys
  unless extra_keys.size == 0
    errors.add(:base, 'You cannot add keys to the schema')
  end
end

但请注意! MongoMapper不存储值为nil 的键。这会影响上面的only_existing_keys方法,所以你可能需要在某处存储一组有效的密钥。

希望这是一个充分的起点。

答案 1 :(得分:0)

你可以引入这样的自定义验证:

before_update :check_username
validate :read_only

def check_username
  @temp_username = self.username
end

def read_only
  false if self.username != self.temp_username
end

不确定这是否有效但你有回调和验证,你可以使用它们来确保没有任何改变。

http://mongomapper.com/documentation/plugins/callbacks.html http://mongomapper.com/documentation/plugins/validations.html