Mongoid忽略嵌入文档的长度验证

时间:2016-01-21 00:46:54

标签: ruby-on-rails mongodb mongoid

我有以下型号:

class Man < User

  field :surname,        type: String,  default: ""
  field :name,           type: String,  default: ""

  NAME_LENGTH = 1..50
  validates :surname, length: {in: NAME_LENGTH}, allow_blank: true
  validates :name,    length: {in: NAME_LENGTH}, allow_blank: true
  validates :father,  length: {in: NAME_LENGTH}, allow_blank: true

  field :birthday,       type: Integer #Timestamp

  field :about, type: String

  ABOUT_LENGTH = 2000
  validates :about, length: {maximum: ABOUT_LENGTH}, allow_blank: true

  embeds_many :skills
  MAX_SKILLS_COUNT = 10
  validates :skills, length: {maximum: MAX_SKILLS_COUNT}
  #user got unique skills
  index({login: 1, 'skills.caption_to_index': 1}, {unique: true, sparse: true})

end

嵌入式技能模型:

class Skill
  include Mongoid::Document

  CAPTION_LENGTH = 1..50
  CAPTION_FILTER = /[^a-zа-я0-9]/

  field :caption,          type: String
  field :caption_to_index, type: String
  field :order,            type: Integer

  embedded_in :man

  validates :caption, length: {in: CAPTION_LENGTH}
  validates :order,   presence: true

  before_save do |document|
    document.caption_to_index = document.caption.downcase.gsub(CAPTION_FILTER,'')
  end
end

麻烦的是,当我做这样的事情时,mongoid会忽略长度验证:

pry(main)> u = Man.find_by(login:'tester')
pry(main)> s3 = Skill.new(caption:'JavaScript',order:1)
pry(main)> u.skills << s3 

我可以无限次重复u.skills << s3次,并且驱动程序会立即将其保存到数据库中。

另一个问题是唯一索引不起作用:

index({login: 1, 'skills.caption_to_index': 1}, {unique: true, sparse: true})

所有索引都是通过rake:mongoid:create_indexes

成功创建的

驱动程序允许使用相同的标题保存文档,这里是mongo shell中文档的一部分作为证明:

        {
                "_id" : ObjectId("56a0218167e92c3b8b000000"),
                "caption" : "JavaScript",
                "order" : 1,
                "caption_to_index" : "javascript"
        },
        {
                "_id" : ObjectId("56a0218167e92c3b8b000000"),
                "caption" : "JavaScript",
                "order" : 1,
                "caption_to_index" : "javascript"
        },
        {
                "_id" : ObjectId("56a0218167e92c3b8b000000"),
                "caption" : "JavaScript",
                "order" : 1,
                "caption_to_index" : "javascript"
        },
        {
                "_id" : ObjectId("56a0218167e92c3b8b000000"),
                "caption" : "JavaScript",
                "order" : 1,
                "caption_to_index" : "javascript"
        }

唯一性的测试用例也失败了:

require 'rails_helper'
include ApplicationHelper

describe Skill do
  before :each do
    @attrs = attributes_for :tester_man
    @tester = create :tester_man
    expect(@tester).to be_valid
    expect(@tester.persisted?).to be true
  end

  it "skill caption is unique" do
    #debugger
    s1_good = Skill.new(caption:'<<cap Tion ..%#',order:2)
    s2_good = Skill.new(caption:'other_caption',order:4)
    s3_bad  = Skill.new(caption:'CAPTION',order:1)
    expect(s1_good).to be_valid
    expect(s2_good).to be_valid

    @tester.skills = [s1_good,s2_good]
    @tester.save
    expect(@tester).to be_valid

    s3_bad  = Skill.new(caption:'CAPTION',order:1)
    @tester.skills << s3_bad
    expect(@tester).not_to be_valid
  end
end

如何让代码按预期运行?

0 个答案:

没有答案