严重困难:没有使用fields_for触发嵌套资源的验证

时间:2012-07-08 12:09:04

标签: ruby-on-rails ruby-on-rails-3 validation activerecord nested-attributes

我严重关注我有用户和个人资料模型的问题。 无论我尝试什么,似乎都没有触发任何配置文件属性的验证

  • 个人资料模型属于用户。用户has_one个人资料
  • 在注册表单上使用fields_for显示一些个人资料字段(性别,城市和国家/地区)
  • 无论我做了什么,我都无法让验证适用于性别和城市(fields_for个人资料字段)

我的表单:

- title t(:title, :scope => :register)
%h1= yield(:title)

  = simple_form_for(resource, :as => resource_name, :html => { :class => 'form-horizontal' } , :validate => true , :url => registration_path(resource_name)) do |f|

    = f.input :username,                  :label  => t(:username)
    = f.input :email,                     :label  => t(:email),
                                          :hint   => t(:hint_email_visible)
    = f.input :password,                  :label  => t(:password), :require => true
    = f.input :password_confirmation,     :label  => t(:password_confirm)


    - resource.build_profile
    = f.fields_for :profile do |f|

      #div

        = f.hidden_field :form, :value => "signup"

        .clear

        = f.input :gender,                :collection => [['Male', 'male'], ['Female', 'female']],
                                          :as => :radio

    = f.input :city,
              :readonly => "readonly",
              :label => t(:city)

    .ruler

    = f.input :country,
              :label => "Your country",
              :collection => [DataCountry.where(:code => 155).first],
              :value => @city,
              :id => "country",
              :name => "country"

    .clear


    = f.button :submit, t(:submit, :scope => :register) + " »"

我的用户模型有:

  accepts_nested_attributes_for :profile

我的带有验证的个人资料模型如下:

  validates_presence_of :gender
  validates_presence_of :city
  validates_presence_of :country

我的参与:

-- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
utf8: ✓
authenticity_token: <mytokenhere>
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  invite_code: ''
  username: username
  email: ''
  password: ''
  password_confirmation: ''
  profile_attributes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
    form: signup
    gender: male
    dob(3i): '9'
    dob(2i): '7'
    dob(1i): '1942'
    city: 'somevalue'
    country: 'somevalue'
commit: Register »
action: create
controller: registrations

Rails控制台确实:

User.new


 => #<User id: nil, email: "", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, password_salt: nil, confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, authentication_token: nil, username: nil, is_blocked: nil, is_deleted: nil, role: nil, slug: nil, created_at: nil, updated_at: nil, last_seen: nil, credits: nil, invite_code: nil, is_moderated: nil, locale: nil, status: nil, login_token: nil> 

Profile.new

 => #<Profile id: nil, user_id: nil, gender: nil, country: nil, state: nil, city: nil, status: nil, counter_cache: nil> 

- 更新于2012年7月19日

我添加了

    - @user.errors.full_messages.each do |message|
  = message
  .clear

到表格中查看究竟发生了什么,这会引发以下错误列表:

Email can't be blank
Email can't be blank
Password can't be blank
Password can't be blank
Profile city can't be blank
Profile gender can't be blank
Profile is invalid
Username can't be blank
Password confirmation can't be blank 

所以似乎检查了验证.... 但是没有应用错误样式!该个人资料也无效????我不确定,但这是指

3 个答案:

答案 0 :(得分:3)

首先,您粘贴的参数包括个人资料的城市,国家和性别的值。如果这是准确的,则验证应该通过,因为Profile模型验证了这3个字段的存在 - 并且它们存在。

我还注意到您在视图中正在执行resource.build_profile,这应该构建属于该用户的默认配置文件。如果在实例化期间在配置文件中分配了任何值,这将导致它们进入表单,最终进入params哈希。

所以我的猜测是你在整个行的某个地方填充字段,可能在UserProfile模型中。您应该再次检查它们,特别是在初始化新配置文件期间。

从我给出的数据中我可以猜到这一切。如果你仍然找不到问题,你可以尝试提交它(或者一个单独的应用程序,如果你不舒服地分享你的真实应用程序,再现问题)到GitHub,以便我们可以更直接地分析问题。

编辑:刚刚注意到,在你的赏金中你写道:

  

任何人都可以提供嵌套资源和验证的工作示例

因此,请参阅https://github.com/sinisterchipmunk/rubytastic以获取一个简单的用户验证示例,其中包含一个配置文件的嵌套属性,模仿您的问题。它会验证User#emailProfile#cityProfile#countryProfile#gender

答案 1 :(得分:2)

检查数据库集中是否有任何默认值。似乎在params形式中,您已粘贴问题,性别已通过值male。即使你没有检查任何性别的东西,这种形式的参数是否通过了?在这种情况下,必须是数据库中的性别字段必须具有性别默认值male的情况。在这种情况下,即使新的Profile模型对象的性别属性也会为male,因此它会传递验证并将性别保存为male在数据库中。例如,我在users表中有一个布尔字段is_admin,并将其默认值设置为false0。如果我这样做:

User.new
=>  #<User id: nil, name: nil, email: nil, is_admin: false>

您可以看到is_admin属性设置为false而不是nil。现在,如果我们没有为is_admin传递任何值,那么它在数据库中将保存为false,并且也不会触发is_admin字段的验证,因为它存在于false字段中对象的属性(值为{{1}})。

答案 2 :(得分:0)

根据本主题中的建议我花了很多时间来尝试解决此问题,解决方案非常简单我找到了而不是

<强> WRONG:

- resource.build_profile

<强>正确:

- resource.build_profile unless resource.profile

这样做不是干净的配置文件,但使用旧的,如果它可用...所以不清除所有的错误!希望这有助于将来的某个人!

相关问题