验证在具有多个模型的表单中失火 [英] Validations misfiring in a form with multiple models

查看:36
本文介绍了验证在具有多个模型的表单中失火的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个网络应用程序,用于保存用户的目标和任务,其中用户有_many 个目标,一个目标有_多个任务.当我尝试将目标和任务保存在一起时,我不断收到验证错误,提示任务目标不能为空"和任务内容不能为空",即使它们显然不是.我确定问题不在于实际的形式,而在于目标控制器的新建"或创建"代码,但无论我尝试什么,我似乎都无法正确解决.关于为什么任务模型的验证失败的任何想法?我已经在这个问题上工作了太久,我即将放弃.我已经包含了目标控制器、目标模型、任务模型和调试信息.如果您需要查看任何其他代码,请告诉我.

I'm building a web app that saves a user's goals and tasks, where a user has_many goals, and a goal has_many tasks. When I try to save a goal and task together, I keep getting validation errors saying "Tasks goal can't be blank" and "Tasks content can't be blank," even though they clearly aren't. I'm certain the problem isn't with the actual form, but with the goal controller's 'new' or 'create' code, but whatever I try, I can't seem to get it right. Any ideas on why the validations for the task model are misfiring? I've been working on this issue for too long and I'm about to give up. I've included the goal controller, goal model, task model, and debug info. If you need to see any other code, let me know.

目标控制器:

def new 
  @title = "New Goal"
  @goal = Goal.new
  @goal.tasks.build
end     

def create
  @user = current_user
  @goal = @user.goals.build(params[:goal])
  @task = @goal.tasks.build(params[:goal][:task])
  if @goal.save
    flash[:success] = "Goal created!"
    redirect_to user_path(@user) 
  else
    render 'new'
  end
end

目标模型:

# Table name: goals
#
#  id              :integer         not null, primary key
#  user_id         :integer
#  content         :string(255)
#  completed       :boolean
#  completion_date :date
#  created_at      :datetime
#  updated_at      :datetime
#

class Goal < ActiveRecord::Base

  attr_accessible :content, :completed, :completion_date
  belongs_to :user
  has_many :tasks, :dependent => :destroy
  accepts_nested_attributes_for :tasks

  validates :user_id, :presence => true
  validates :content, :presence => true, :length => { :maximum => 140 }

end

任务模型:

#  id              :integer         not null, primary key
#  goal_id         :integer
#  content         :string(255)
#  occur_on        :date
#  recur_on        :string(255)
#  completed       :boolean
#  completion_date :date
#  created_at      :datetime
#  updated_at      :datetime
#

class Task < ActiveRecord::Base

  attr_accessible :content, :occur_on, :recur_on, :completed
  belongs_to :goal

  validates :goal_id, :presence => true
  validates :content, :presence => true, :length => { :maximum => 140 }

end

保存失败后的调试转储:

Debug Dump after an unsuccessful save:

--- !map:ActiveSupport::HashWithIndifferentAccess 
utf8: "\xE2\x9C\x93"
authenticity_token: NF/vVwinKQlGAvBwEnlVX/d9Wvo19MipOkYb7qiElz0=
goal: !map:ActiveSupport::HashWithIndifferentAccess 
  content: some goal
  tasks_attributes: !map:ActiveSupport::HashWithIndifferentAccess 
    "0": !map:ActiveSupport::HashWithIndifferentAccess 
      content: some task
commit: Submit
action: create
controller: goals

推荐答案

这是嵌套属性的问题.您无法验证嵌套模型中封装模型的存在(在您的情况下,您无法验证 Task 中的goal_id 的存在).运行验证时,目标尚未保存,因此没有 id,因此无法分配.

This is a problem with nested attributes. You cannot validate the presence of the encapsulating model from the nested model (in your case, you cannot validate the presence of goal_id from Task). When validations are run the goal is not yet saved, and thus has no id, so it is impossible to assign it.

您可以消除导致问题的验证,或者不使用内置的嵌套属性.在后一种情况下,您需要添加自己的逻辑来首先保存目标,然后创建任何嵌套任务.

You can either eliminate the validation that is causing the problem, or not use the built-in nested attributes. In the latter case, you would need to add your own logic to first save the goal and then create any nested tasks.

糟糕,是吧?我希望有人能为此提出一个很好的解决方案……如果我有空闲时间,我可能会努力解决这个问题.

Bummer, huh? I wish someone would come up with a good solution for this...maybe I'll work on it if I ever get some free time.

这篇关于验证在具有多个模型的表单中失火的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆