Mongoid中first_or_create与first_or_create!两个方法有什么区别
Mongoid 中
first_or_create 与 first_or_create! 的区别与使用规则 两个方法的基础逻辑一致:优先按传入的查询条件匹配集合内第一条符合要求的文档,若没有匹配结果则尝试用查询条件+传入的补充属性新建文档,核心差异集中在「新建文档校验失败」时的处理逻辑:
first_or_create行为规则
当新建文档触发模型校验(validations)未通过时,不会抛出异常,会直接返回未持久化到数据库的无效文档对象,你可以通过返回对象的errors属性获取具体校验失败原因。
示例代码:class User include Mongoid::Document field :email, type: String field :age, type: Integer validates :email, presence: true end # 缺失必填属性email,新建校验失败 user = User.where(age: 20).first_or_create user.persisted? # 返回 false,说明没有存入数据库 user.errors.full_messages # 返回 ["Email can't be blank"]适用场景:需要在业务流程里手动处理创建失败分支,不希望通过异常捕获做流程控制的场景,比如表单提交后把校验错误回显给用户的业务逻辑。
first_or_create!行为规则
当新建文档触发模型校验未通过时,会直接抛出Mongoid::Errors::Validations异常,不会静默返回未保存的对象。
示例代码:# 同样缺失必填属性email,以下代码会直接抛出异常 begin User.where(age: 20).first_or_create! rescue Mongoid::Errors::Validations => e # 可在异常分支中做错误日志记录、告警等处理 puts e.document.errors.full_messages end适用场景:你确认传入参数完全符合校验规则,创建失败属于预期外的程序错误,需要异常直接抛出触发监控告警,或者配合事务做回滚逻辑的场景。
注意:两个方法在匹配到已有文档时,都不会用传入的额外属性更新已有文档内容,不要和upsert类更新/插入方法的逻辑混淆。
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

