根据深层嵌套形式的当前用户更改运行哪些Rails验证

时间:2010-08-05 16:41:35

标签: ruby-on-rails validation nested-forms

我正在使用嵌套表单,该表单包含总共7个模型,每个模型都有不同的验证。简单地编辑表单时,验证运行并显示正常,并正确保存数据。但是,我需要根据提交表单的人员运行不同的验证(例如,管理员可以跳过一些其他必需的字段)。

我以为我可以通过在我的模型中使用attr_accessible:editing_user来跳过某些验证,然后在控制器中设置它。

class ModelExample < ActiveRecord::Base
  attr_accessible :editing_user
  validates_presence_of :email, :unless => "editing_user == 'admin'"
end

class ModelExamplesController < ActionController::Base
  def create
    @model_example = ModelExample.new(params[:model_example])
    @model_example.editing_user = 'admin'
    @model_example.save
  end
end

我在嵌套模型中使用了这个基本结构,检查是否可以正确保存。这是怪异行为开始的地方。出于某种原因,看起来ActiveRecord试图多次保存嵌套模型,每次都运行验证。这让我很奇怪的是我调用了@ model_example.save,如果失败则应该返回false。但是,第一次验证通过(因为edit_user已设置),但后来的验证失败并引发异常,因此正常的.save方法最终会引发异常而不是返回。

有没有人知道如何避免ActiveRecord执行所有额外的验证和保存,或者如何在这些重复操作中保留edit_user?

1 个答案:

答案 0 :(得分:1)

公顷!只是做了这个昨天,好吧,几乎相同的用例无论如何(坚持用户)。这就是我如何解决它的问题(我的好友Jason Dew是我所复制的):

class User < ActiveRecord::Base

  module ClassMethods
    attr_accessor :current
  end

  extend ClassMethods
end

此代码块将一个单例访问器:current添加到User类方法,并可以作为User.current调用。更好看这个名为self.currrent

的方法

然后在app控制器

before_filter :require_user #=> which in this case goes off and sets the current_user var
before_filter {|c| User.current = current_user}

将app控制器传递给块并设置User.current var。

然后在任何其他模型中

class MyClass < ActiveRecord::Base
  def log
    "This was done by #{User.current}"
  end
end