验证在具有多个模型的表单中失效

时间:2011-07-06 21:21:20

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

我正在构建一个Web应用程序,用于保存用户的目标和任务,其中用户具有多个目标,并且目标包含多个任务。当我尝试将目标和任务保存在一起时,我不断收到验证错误,说“任务目标不能为空”和“任务内容不能为空”,即使它们显然不是。我确定问题不在于实际形式,而在于目标控制器的“新”或“创建”代码,但无论我尝试什么,我似乎无法做到正确。关于为什么任务模型的验证失误的任何想法?我一直在研究这个问题太久了,我即将放弃。我已经包含了目标控制器,目标模型,任务模型和调试信息。如果您需要查看任何其他代码,请与我们联系。

目标控制器:

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
保存失败后

调试转储:

--- !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

1 个答案:

答案 0 :(得分:1)

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

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

糟糕,是吧?我希望有人能为此提出一个很好的解决方案...如果我有空闲时间,也许我会继续努力。