【问题标题】:How to validate a mongoid field based on another mongoid field?如何基于另一个 mongoid 字段验证一个 mongoid 字段?
【发布时间】:2014-05-16 02:30:42
【问题描述】:

我切换到 nosql 并正在与 Sinatra 一起玩 Mongoid。我还是新手,我被这个问题难住了。

class Item
    field :name, type: String
    field :category, type: Moped::BSON::ObjectId    # holds _id of the category object
    field :cover_type, type: String

    validates_presence_of :category
    validates_inclusion_of :cover_type, in:["Hardcover", "Softcover"]
end

class Category
    field :name

    validates_inclusion_of :name, in:["Books", "Movies", "Ebooks"]
end

想象一家商店出售书籍、电影和电子书,并且出售的每件商品都属于这三个类别之一。如果某个项目列在“书籍”类别下,则该项目需要有一个名为 cover_type 的字段。此外,cover_type 只能是“精装”或“平装”。

当保存一个项目时,我如何将项目类中的验证拼凑在一起,以便项目在图书类别中,因此需要存在字段cover_type,该字段也被验证为“精装”或“平装”?

如果项目不是一本书,那么cover_type 可以为空。

【问题讨论】:

    标签: ruby sinatra mongoid


    【解决方案1】:

    Mongoid 模型继承 ActiveModel 验证。你可以写一个custom validator method

    class Item
      validates :cover_type_must_be_valid, if: :book?
    
      def book?
        Category.find(category).name == 'Books'
      end
    
      def cover_type_must_be_valid
        errors.add(:cover_type, 'must be Hardcover or Softcover') unless %w{Hardcover Softcover}.include? cover_type
      end
    end
    

    book? 方法令人不快;为什么不在Item 上使用belongs_to :category,在Category 上使用has_many :items

    编辑:如果您使用has_manybelongs_to,这就是book? 的样子:

    def book?
      category.name == 'Books'
    end
    

    没有什么不同,但您肯定会在整个应用程序中访问item.category,我不明白您为什么不想让它变得更简单。

    【讨论】:

    • 你能解释为什么books? 不愉快吗?而如果我在Categorybelongs_to :category 上使用has_many :items,我将如何强制Item 中的cover_type 只能是平装和精装?
    • 这很令人不快,因为它必须通过 ID 查找 Category,而 Mongoid/ActiveModel 正是出于这个原因给你 belongs_to。如果您使用这些便捷方法,我已经更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    相关资源
    最近更新 更多