【发布时间】:2012-09-18 00:48:34
【问题描述】:
我正在使用 ActiveModel 使我的无表模型感觉像 ActiveRecord 模型。我正在使用自定义商店,我需要能够验证记录的唯一性。
如何使用 ActiveModel 实现所需的唯一性检查?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 activerecord activemodel
我正在使用 ActiveModel 使我的无表模型感觉像 ActiveRecord 模型。我正在使用自定义商店,我需要能够验证记录的唯一性。
如何使用 ActiveModel 实现所需的唯一性检查?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 activerecord activemodel
我最终做了这样的事情:
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
也许有人可以告诉我这是否是正确的方法
【讨论】:
检查这个 railscasts,它可能会有所帮助
http://railscasts.com/episodes/193-tableless-model
完成模型后,添加验证,然后添加@model.valid?
【讨论】:
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
【讨论】:
:name的唯一性?我认为验证唯一性是一种特殊情况,它的正确性在很大程度上依赖于数据存储,并且无法抽象到根本不需要表的 ActiveModel 中。