我想知道是否还有一个属性键只读。这意味着它只能在创建对象时分配
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?
答案 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