如何获取rails中保存的值?

时间:2012-04-15 17:41:27

标签: ruby-on-rails ruby ruby-on-rails-3 validation

好的,我有一个名为Tire的模型,我无法更新某些保留名称上的名称字段

class Tire < ActiveRecord::Base

  RESERVED_TIRES = ['Michelin', 'Good Year', 'Firestone']

  before_update :reserved_tires

  def reserved_tires
    if RESERVED_TIRES.include?(self.name)
      self.errors.add(:base, "Cant be changed")
      false
    end
  end
end

我需要不允许用户更新任何字段,当前名称是保留字...这适用于除用户更新名称之外的所有字段。

例如,用户更新为“Michelinnnn”然后它允许更新,因为self.name是“Michelinnnn”而不是“米其林”,它保存在数据库中。关于如何解决这个问题的任何想法

4 个答案:

答案 0 :(得分:3)

如果您的意思是如果保留更改名称之前您不想允许任何更改,那么您可以访问旧名称 name_was

答案 1 :(得分:1)

所以问题是与保留名称相似但不相同的字符串?使用正则表达式而不是精确的字符串匹配来捕获“michelinnnn”示例:

RESERVED_TIRES = [/michelin/i, /good\s*year/i, /firestone/i]
...
if RESERVED_TIRES.find{|r| self.name =~ r}

内置的Rails函数是validates_exclusion_of,但我不知道它是否可以处理正则表达式的数组。

然而,这只会捕获某些类似的名字。 There are more general ways to calculate string similarity,但对于这类问题没有防水解决方案。

答案 2 :(得分:1)

首先,您可能希望使用验证而不是before_update

class Tire < ActiveRecord::Base
  RESERVED_TIRES = ['Michelin', 'Good Year', 'Firestone']
  validate :reserved_tires, :unless => :new_record?

private

  def reserved_tires
    if RESERVED_TIRES.include?(self.name)
      self.errors.add(:base, "Cant be changed")
    end
  end
end

:unless => :new_record?会跳过新记录的验证,因此您可以创建它们,但会阻止更改。

然后添加另一个验证以捕获他们尝试更改名称:

validate :cant_change_reserved_name, :if => :name_changed?
#...
def cant_change_reserved_name
  if RESERVED_TIRES.include?(self.name_was)
    self.errors.add(:name, "You cannot change a reserved name.")
  end
end

答案 3 :(得分:1)

应该这样做:

name_allowed = RESERVED_TIRES.inject(true) { |is_allowed, tire_name|
  is_allowed &&= !self.name.include?(tire_name)
}
unless name_allowed
  # add error
end