【问题标题】:ActiveRecord Nested validation while using embedded documents: Mongoid使用嵌入文档时的 ActiveRecord 嵌套验证:Mongoid
【发布时间】:2015-04-13 18:15:51
【问题描述】:

我将课程列表文档嵌入到名为课程的父文档中。课程列表属于示范课程。

课程表模型:

     include Mongoid::Document
  @schema = {
      'type' => 'object',
      'properties' => {
          # 'id'               => { 'type' => 'string' },
          'course_order_id'  => { 'type' => 'integer'}, #Explicit course ID order
          'course_id'        => { 'type' => 'string' }
      }
  }


  @modelName = 'courselist'
  @collectionName = 'courselist'

  field :course_order_id,   type: Integer
  belongs_to :course #Course model 

  embedded_in :curricula, class_name:"Models::Persistence::Curriculum"

课程表.rb

     @schema = {
      'type' => 'object',
      'properties' => {
          'id'                       => { 'type' => 'string' },
          'title'                    => { 'type' => 'string'  },
          'description'              => { 'type' => 'string'  },
          'cover_image_url'          => { 'type' => 'string'  },
          'trailer_url'              => { 'type' => 'string'  },
          'courselist'               => {'type' => 'array'},
          'price'                    => { 'type' => 'float'   },
          'currency_id'              => { 'type' => 'string' },
          'publisher_id'             => { 'type' => 'string' },
          'certification_ids'        => { 'type' => 'array'   },
          'version'                  => { 'type' => 'integer' },
          'status'                   => { 'type' => 'string'}
      }
  }
  @modelName      = 'curricula'
  @collectionName = 'curricula'


  store_in collection: 'curricula'

  field :title,                     type: String
  field :description,               type: String

  embeds_many :courselist

在课程路线上执行 GET 时得到的 JSON:

           "id": "552bfae243534fcdd2a20000",
        "courselist": [
            {
                "_id": {
                    "$oid": "552bfae243534fcdd2a30000"
                },
                "course_order_id": 1,
                "course_id": {
                    "$oid": "552bfae143534fcdd2930000"
                }
            },
            {
                "_id": {
                    "$oid": "552bfae243534fcdd2a40000"
                },
                "course_order_id": 2,
                "course_id": {
                    "$oid": "552bfae243534fcdd29f0000"
                }
            }
        ]
    }

我的疑惑:

  1. $oid 是什么意思?有没有办法将它覆盖到一个不涉及 $ 作为前缀的键?
  2. 如何验证课程列表中所有对象的课程 ID?现在我已经写了这个但是它不起作用:(

    validate :validate_courselist
    
    def validate_courselist
    if (courselist == nil)
      return
    end
    if (courselist.uniq.length != courselist.length)
      errors.add :base, "Course ids should be unique"
    end
    courselist.each do |course_id|
      if (Models::Persistence::Course.find_by( _id: course_id) == nil) #this is my issue. How can I get the $oid of the course object??
        errors.add :base, "Course id #{course_id} could not be found"
      end
    end
    

    结束 Edit1:上述验证是在嵌入式父模型上完成的。应该在孩子身上做吗?还是在父母那里?还是没关系? 提前致谢。

【问题讨论】:

    标签: ruby validation activerecord mongoid


    【解决方案1】:

    $oid 的内容正是 BSON::ObjectId 将自身序列化为 JSON 的方式。你可以自己解包,或者,如果你想在你的模型实例上继续使用as_jsonto_json,你可以猴子补丁BSON::ObjectId

    module BSON
      class ObjectId 
        def to_json(*) 
          to_s.to_json
        end
        def as_json(*)
          to_s.as_json
        end
      end 
    end
    

    我修改补丁以避免一直处理$oid 的东西。

    就验证而言,我会让每件事都验证其级别的数据。您有两个单独的验证:

    1. 课程列表中没有重复。
    2. 每门课程都是一门课程。

    Curriculum 将处理整个列表:

    validate :no_duplicates
    
    def no_duplicates
      if(course_list.map(&:course_id).uniq.length != course_list.length)
        #...
      end
    end
    

    请注意,我们正在查看嵌入文档中的 course_ids 以检查唯一性。每个嵌入的文档都有自己的_id,而_id 是通常用于比较的;我们不关心那些,我们关心独特的课程,所以这就是我们所关注的。

    那么您的Courselist 可以自行处理有效性:

    validates_presence_of :course
    

    检查course 的存在将尝试将课程拉出MongoDB。如果您认为这太昂贵了,您可以将其替换为直接存在性检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2016-09-17
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多