在验证user_id时,Rails3关联和accepts_nested_attributes_for失败

时间:2012-12-07 12:57:56

标签: ruby ruby-on-rails-3 associations nested-attributes

我正在关注Rails Tutorial为自己做一个小项目,然后尝试进步。

我正面临一个问题,我找到了解决方案,但我真的很感激任何想法和意见,因为要使其工作我必须在关联中禁用验证。

上下文如下:应用程序(实际上它的名字大...)让用户跟踪他们的体重。我希望当用户注册时,他/她会在旅途中输入第一个小节。

以下是简化模型:

User.rb

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation, :measures_attributes

  has_secure_password

  has_many :measures, dependent: :destroy
  accepts_nested_attributes_for :measures

  # here goes validations before_save, etc. taken from the Rails Tutorial
end

Measure.rb

class Measure < ActiveRecord::Base
  attr_accessible :weight
  belongs_to :user

  # This is kind where the problem is...
  # If I deactivate the validation for user_id everyhing goes fine
  validates :user_id, presence: true
  validates :weight, presence: true, numericality: { greater_than: 0 }

  default_scope order: 'measures.created_at ASC'
end

这是用户控制器

class UsersController < ApplicationController

  # GET /users/new
  def new
    @user = User.new
    @user.measures.build
  end

  # POST /users
  def create

    @user = User.new(params[:user])

    if @user.save
      sign_in @user
      flash[:success] = "Hi #{@user.name}. Welcome !"
      redirect_to @user
    else
      render :new
    end
  end

end

以下是用户的部分表单:

<%= form_for(user) do |user_form| %>
  <%= render 'shared/error_messages', object: user_form.object %>

  <%= render 'users/fields', user_builder: user_form %>

  <%= user_form.fields_for :measures do |measure_fields| %>
    <%= render 'measures/fields', measure_builder: measure_fields, full: true %>
  <% end %>

  <%= user_form.submit submit_text, class: 'btn btn-large btn-primary' %>
<% end %>

即使我正确填写表单,我也会收到此错误:

* Measures user can't be blank

我发现使其工作的唯一方法是摆脱测量模型中存在的:user_id验证。我想强调的是,当此验证关闭时,将保存用户,度量将保存并与新创建的用户正确关联。

我做错了吗? Measure模型中的:user_id状态验证是否真的有用(它在Rails教程中,对我来说非常有意义)?如果是,为什么测量验证在启用时失败?

提前多多感谢。

2 个答案:

答案 0 :(得分:1)

您可以尝试验证:user而不是user_id。然后,即使用户尚未保存,它们可能会在内存中关联两者。

答案 1 :(得分:0)

我想我可能在您的代码中发现了一个错误,导致您看到的错误。

在新控制器中,您专门创建了一个关联:

@user.measures.build

在您的创建控制器中,您可以根据传入的字段创建新元素。

@user = User.new(params[:user])

在某些情况下,相关元素将被删除。我不记得,如果它没有验证,或者如果有一个选项需要设置以使其丢弃,则默认情况下是否会发生这种情况。

我认为您可能需要添加

@user.measure.build if @user.measures.empty?
create之前的else控制器render :new子句中

我不知道你是否真的遇到了这个问题,但它可以解释为什么没有设置你User的关联。