【问题标题】:How to use validates_uniqueness_of with ActiveModel?如何将 validates_uniqueness_of 与 ActiveModel 一起使用?
【发布时间】:2012-09-18 00:48:34
【问题描述】:

我正在使用 ActiveModel 使我的无表模型感觉像 ActiveRecord 模型。我正在使用自定义商店,我需要能够验证记录的唯一性。

如何使用 ActiveModel 实现所需的唯一性检查?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord activemodel


    【解决方案1】:

    我最终做了这样的事情:

    class Theme < Base
    
      include ActiveModel::Validations
    
      attr_accessor :id, :name
      validate      :uniqueness_of_theme_name, :on => :create
    
      def initialize(attrs = {})
        attrs.each do |name, value|
          send("#{name}=", value)
        end
      end
    
      def uniqueness_of_theme_name
        errors.add(:name, "name is already in use") unless Theme.find_by_name(name).nil?
      end
    
      def self.find_by_name(name)
        return store.find({ 'name' => "/^#{name}$/i" }).any?
      end
    
      def self.create(attributes = {})
        theme = Theme.new(attributes)
        theme.save
    
        return theme
      end
    
      def persisted?
        id && !id.nil?
      end
    
      def save()
        # only call validation during create context
        context = persisted? :update : :create
        false if invalid?(context)
        store.save(self)
        true
      end
    
      def self.create(attrs = {})
        theme = Theme.new(attrs)
        theme.save
        theme
      end
    
    end
    

    也许有人可以告诉我这是否是正确的方法

    【讨论】:

    • 我不明白,你在哪里存储这个主题,所以它可以被验证为唯一的,
    • @RodrigoZurek,我的商店实际上是 mongodb。我已经更新了上面的代码。它不完整,但它应该给你一个更好的主意。
    • 你的 Base 类包括什么?
    • 基类包含一些让模型与 mongodb 交互的基本代码
    【解决方案2】:

    检查这个 railscasts,它可能会有所帮助

    http://railscasts.com/episodes/193-tableless-model

    完成模型后,添加验证,然后添加@model.valid?

    【讨论】:

    • 我知道该教程是关于无表模型的,但它没有任何唯一性检查示例。
    【解决方案3】:

    ActiveModel 可以根据另一个railscasts 使用,更适合该用例。

    class Theme
    
      include ActiveModel::Validations
      include ActiveModel::Conversion
      extend ActiveModel::Naming
    
      attr_accessor :id, :name
    
      validates :name, uniqueness: true, on: :create
    
      def initialize(attributes = {})
        attributes.each do |name, value|
          send("#{name}=", value)
        end
      end
    
      def persisted?
        false
      end
    end
    

    【讨论】:

    • @mikhailob,上面的代码是根据什么检查:name的唯一性?我认为验证唯一性是一种特殊情况,它的正确性在很大程度上依赖于数据存储,并且无法抽象到根本不需要表的 ActiveModel 中。
    • @Arman ActiveModel 验证确实会在您尝试将数据保存到 Ruby 对象之前调用 save(或显式 valid? 方法) MongoDB(或任何你想要的)。 ActiveModel 是一种抽象,可以帮助您使用像 ActiveRecord table-behind 模型这样的普通对象。
    猜你喜欢
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多