我在一个表单中有三个字段,在另一个表单中有两个字段(与前面的表单相同,只是缺少一个字段)。我只想验证较小表单中的两个字段,但问题是它验证了所有三个字段。
我写了以下逻辑:
**
class User < ActiveRecord::Base
validate :validate_form #for form with 2 fields
private
def validate_form
if :classify_create
self.errors.add(:weight, "need weight") if weight.blank?
self.errors.add(:height, "need height") if height.blank?
end
end
# Validations of attributes (for form with three fields)
validates :weight, :presence => true
validates :height, :presence => true
validates :gender, :presence => true
end**
这是我的控制器操作:基本上我写了两个独立的创建:
**# for form with two fields
def classify
@user = User.new
@title = "Classify"
end
def classify_create
@user = User.where("weight = ? and height = ?", params[:weight] ,params[:height])
end
# for form with three fields
def new
@user = User.new
@title = "Train"
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to @user
else
@title = "Train"
render 'new'
end
end**当我提交到两个字段的表单时,它也给了我一个性别错误,并重定向到具有三个字段的表单的页面。我该怎么做呢?
任何帮助都将不胜感激。
致敬,阿伦
发布于 2012-01-30 10:43:24
首先,我不会使用 classify作为方法名。您可能会与ActiveSupport提供的核心inflector冲突。叫它classification之类的吧。
其次,您的验证在create方法中的if @user.save上运行。
在classify_create中,您可以使用User.where(...),这是一种查找器方法。您正在提取一个匹配的记录并将其设置为@user。这不会运行验证,但您会收到验证错误。您正在发布到create,而不是classify_create。糟糕的路由将导致这种情况。
让我们先来讨论一下条件验证。在User模型中,创建一个变量作为性别验证的旁路开关。然后告诉您的验证在运行之前检查此绕过开关是否为false:
User < ActiveRecord::Base
attr_accessor :skip_gender # defaults to nil (false)
# ...
validates :gender, :presence => true, :if => :validate_gender? # validate if...
# ...
private
def validate_gender?
!self.skip_gender # true = run validation, false = skip validation
end
# ...
end接下来,清理您的控制器。编写两个create方法,一个设置开关,一个不设置。(这不是干的):
def new_classification
# for form with two fields
@user = User.new
@title = "Classify"
end
def new
# for form with three fields
@user = User.new
@title = "Train"
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to @user
else
render :action => 'new' # render three-field form
end
end
def create_classification
@user = User.where(:weight => params[:weight], :height => params[:height])
# ... do something with @user ...
@user.skip_gender = true # tell @user to skip gender validation
if @user.save
redirect_to @user
else
render :action => 'new_classification' # render two-field form
end
end接下来,调整config/routes.rb以指定到您的自定义方法的路由。
resources :users do
member do
get 'new_classification', :to => 'users#new_classification', \
:as => :new_classification_for
post 'create_classification', :to => 'users#create_classification', \
:as => :create_classification_for
end
end现在更改包含两个字段的表单视图。指定将表单提交到的位置。
<%= form_for @user, :url => create_classification_for_user_url(@user) do |f| %>这应该可以让你用你所拥有的……
发布于 2012-01-30 09:06:26
你的问题是双重的:
简单的解决方案是使用一个单独的控制器来绕过这些限制:
def create_genderless
# Force the issue to an explicit "unknown" state so that
# "unknown" and "missing" can be differentiated.
params[:user][:gender] = 'U'
# And then punt to the existing `create` method.
create
end然后在模型中进行更多的验证,以便更好地衡量
class User < ActiveRecord::Base
validates :gender, :inclusion => { :in => %w[M F U] }
#...
end然后根据需要更新表单以使用UserController#create或UserController#create_genderless。
https://stackoverflow.com/questions/9057668
复制相似问题