Ruby on rails 4 Rails 4,验证嵌套模型
我有两种型号:Ruby on rails 4 Rails 4,验证嵌套模型,ruby-on-rails-4,Ruby On Rails 4,我有两种型号: class Person has_one :user validates :document, uniqueness: true, on: :create class User belongs_to :person accepts_nested_attributes_for :person 然后我为用户提供了一个表单,其中包含了有关人员的信息: <%= form_for @user do |f| %> <%= f.fields_for :
class Person
has_one :user
validates :document, uniqueness: true, on: :create
class User
belongs_to :person
accepts_nested_attributes_for :person
然后我为用户
提供了一个表单,其中包含了有关人员的信息
:
<%= form_for @user do |f| %>
<%= f.fields_for :person do |person_fields| %>
<%= person_fields.label "Document" %>
<%= person_fields.text_field :document %>
<% end %>
<%= f.label "Username" %>
<%= f.text_field :username %>
<% end %>
例如,当我选择/users/edit/1
时,它会向用户加载其个人属性。如果我更改用户名
并保存,则表明文档编号已在使用
,仅在创建
时绕过人员
验证唯一性
我是不是遗漏了什么?这样的验证不应该在嵌套表单上工作吗?嵌套属性允许您通过父项(有一个,有多个)在关联记录上保存属性,而不是通过子项(属于)在父项上保存属性。
你的模型关系不正确;根据Rails,嵌套属性通过父对象对子对象有效,而不是在下面的模型中指定的通过子对象对父对象有效
您的机型
class Person
has_one :user
validates :document, uniqueness: true, on: :create
class User
belongs_to :person
accepts_nested_attributes_for :person (sets up nested attributes for parent)
您可以通过父对象为子对象设置嵌套属性,例如
建议的更改
class Person
has_one :user
validates :document, uniqueness: true, on: :create
accepts_nested_attributes_for :user
class User
belongs_to :person
只有当模型中的嵌套关联设置正确时,表单上的嵌套才会起作用 侧边栏:的美:的逆 这是一个侧栏,但与此上下文相关。的反向\u提供了从子对象到父对象的反向引用。你应该试试这个,看看它是如何为你的应用工作的。这是一件非常好的事情
class Person
has_one :user, inverse_of: person
validates :document, uniqueness: true, on: :create
accepts_nested_attributes_for :user
class User
belongs_to :person, inverse_of: user
调试问题(新增)
我将on::create验证作为测试添加到我的一个模型中。我会要求您在没有模型嵌套的情况下进行类似的测试;我认为在模型中测试on:create的逻辑是有益的,它将验证控制器的操作。然后才在嵌套属性上添加图层。你觉得怎么样
创建时重复字段=>回滚
Started POST "/locations" for 127.0.0.1 at 2015-07-20 08:03:36 -0500
Processing by LocationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Fxxx", "location"=>{"name"=>"Foo", "food_trailer"=>"true", "street"=>"100 Main", "city"=>"Fredericksburg", "state"=>"Texas", "country"=>"US", "phone"=>"", "website"=>"", "short_desc"=>"A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010.", "known_for"=>"Tings", "meats_beef"=>"0", "meats_beef_ribs"=>"0", "meats_pork"=>"1", "meats_pork_ribs"=>"0", "meats_chicken"=>"0", "meats_turkey"=>"0", "meats_sausage"=>"0", "meats_venison"=>"0", "sauce"=>"0", "sides"=>"None"}, "commit"=>"Add Restaurant"}
[1m[36mUser Load (0.0ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1[0m [["id", 8]]
[1m[35m (0.0ms)[0m BEGIN
[1m[36mLocation Exists (46.9ms)[0m [1mSELECT 1 AS one FROM "locations" WHERE "locations"."short_desc" = 'A Texan, Ms. Diana has been cookin'' up barbecue for 50 years and, spreadin'' the “barbecue love” in Paris (France!) since 2010.' LIMIT 1[0m
[1m[35mLocation Exists (0.0ms)[0m SELECT 1 AS one FROM "locations" WHERE ("locations"."latitude" IS NULL AND "locations"."longitude" IS NULL) LIMIT 1
[1m[36m (46.9ms)[0m [1mROLLBACK[0m
编辑时重复字段=>COMMIT
Started PATCH "/locations/46" for 127.0.0.1 at 2015-07-20 08:04:30 -0500
Processing by LocationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxx", "location"=>{"name"=>"Grillrestaurant Rusticana", "street"=>"Grillparzerstraße 5, 81675", "city"=>"München", "state"=>"Alabama", "country"=>"US", "phone"=>"", "website"=>"", "short_desc"=>"A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010.", "known_for"=>"", "meats_beef"=>"0", "meats_beef_ribs"=>"0", "meats_pork"=>"0", "meats_pork_ribs"=>"0", "meats_chicken"=>"0", "meats_turkey"=>"0", "meats_sausage"=>"0", "meats_venison"=>"0", "sauce"=>"0", "sides"=>""}, "commit"=>"Save changes to Restaurant", "id"=>"46"}
[1m[36mLocation Load (0.0ms)[0m [1mSELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT 1[0m [["id", 46]]
[1m[35m (0.0ms)[0m BEGIN
[1m[36mLocation Exists (0.0ms)[0m [1mSELECT 1 AS one FROM "locations" WHERE ("locations"."latitude" = 48.1334073 AND "locations"."id" != 46 AND "locations"."longitude" = 11.6100255) LIMIT 1[0m
[1m[35mSQL (15.6ms)[0m UPDATE "locations" SET "short_desc" = $1, "meats_beef" = $2, "meats_pork" = $3, "meats_beef_ribs" = $4, "meats_pork_ribs" = $5, "meats_chicken" = $6, "meats_turkey" = $7, "meats_sausage" = $8, "meats_venison" = $9, "sauce" = $10, "latitude" = $11, "updated_at" = $12 WHERE "locations"."id" = $13 [["short_desc", "A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010."], ["meats_beef", "f"], ["meats_pork", "f"], ["meats_beef_ribs", "f"], ["meats_pork_ribs", "f"], ["meats_chicken", "f"], ["meats_turkey", "f"], ["meats_sausage", "f"], ["meats_venison", "f"], ["sauce", "f"], ["latitude", 48.13340729999999], ["updated_at", "2015-07-20 13:04:30.437500"], ["id", 46]]
[1m[36m (46.9ms)[0m [1mCOMMIT[0m
嵌套属性允许您通过父项(有一个,有多个)在关联记录上保存属性,而不是通过子项(属于)在父项上保存属性。
你的模型关系不正确;根据Rails,嵌套属性通过父对象对子对象有效,而不是在下面的模型中指定的通过子对象对父对象有效
您的机型
class Person
has_one :user
validates :document, uniqueness: true, on: :create
class User
belongs_to :person
accepts_nested_attributes_for :person (sets up nested attributes for parent)
您可以通过父对象为子对象设置嵌套属性,例如
建议的更改
class Person
has_one :user
validates :document, uniqueness: true, on: :create
accepts_nested_attributes_for :user
class User
belongs_to :person
只有当模型中的嵌套关联设置正确时,表单上的嵌套才会起作用 侧边栏:的美:的逆 这是一个侧栏,但与此上下文相关。的反向\u提供了从子对象到父对象的反向引用。你应该试试这个,看看它是如何为你的应用工作的。这是一件非常好的事情
class Person
has_one :user, inverse_of: person
validates :document, uniqueness: true, on: :create
accepts_nested_attributes_for :user
class User
belongs_to :person, inverse_of: user
调试问题(新增)
我将on::create验证作为测试添加到我的一个模型中。我会要求您在没有模型嵌套的情况下进行类似的测试;我认为在模型中测试on:create的逻辑是有益的,它将验证控制器的操作。然后才在嵌套属性上添加图层。你觉得怎么样
创建时重复字段=>回滚
Started POST "/locations" for 127.0.0.1 at 2015-07-20 08:03:36 -0500
Processing by LocationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Fxxx", "location"=>{"name"=>"Foo", "food_trailer"=>"true", "street"=>"100 Main", "city"=>"Fredericksburg", "state"=>"Texas", "country"=>"US", "phone"=>"", "website"=>"", "short_desc"=>"A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010.", "known_for"=>"Tings", "meats_beef"=>"0", "meats_beef_ribs"=>"0", "meats_pork"=>"1", "meats_pork_ribs"=>"0", "meats_chicken"=>"0", "meats_turkey"=>"0", "meats_sausage"=>"0", "meats_venison"=>"0", "sauce"=>"0", "sides"=>"None"}, "commit"=>"Add Restaurant"}
[1m[36mUser Load (0.0ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1[0m [["id", 8]]
[1m[35m (0.0ms)[0m BEGIN
[1m[36mLocation Exists (46.9ms)[0m [1mSELECT 1 AS one FROM "locations" WHERE "locations"."short_desc" = 'A Texan, Ms. Diana has been cookin'' up barbecue for 50 years and, spreadin'' the “barbecue love” in Paris (France!) since 2010.' LIMIT 1[0m
[1m[35mLocation Exists (0.0ms)[0m SELECT 1 AS one FROM "locations" WHERE ("locations"."latitude" IS NULL AND "locations"."longitude" IS NULL) LIMIT 1
[1m[36m (46.9ms)[0m [1mROLLBACK[0m
编辑时重复字段=>COMMIT
Started PATCH "/locations/46" for 127.0.0.1 at 2015-07-20 08:04:30 -0500
Processing by LocationsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxx", "location"=>{"name"=>"Grillrestaurant Rusticana", "street"=>"Grillparzerstraße 5, 81675", "city"=>"München", "state"=>"Alabama", "country"=>"US", "phone"=>"", "website"=>"", "short_desc"=>"A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010.", "known_for"=>"", "meats_beef"=>"0", "meats_beef_ribs"=>"0", "meats_pork"=>"0", "meats_pork_ribs"=>"0", "meats_chicken"=>"0", "meats_turkey"=>"0", "meats_sausage"=>"0", "meats_venison"=>"0", "sauce"=>"0", "sides"=>""}, "commit"=>"Save changes to Restaurant", "id"=>"46"}
[1m[36mLocation Load (0.0ms)[0m [1mSELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT 1[0m [["id", 46]]
[1m[35m (0.0ms)[0m BEGIN
[1m[36mLocation Exists (0.0ms)[0m [1mSELECT 1 AS one FROM "locations" WHERE ("locations"."latitude" = 48.1334073 AND "locations"."id" != 46 AND "locations"."longitude" = 11.6100255) LIMIT 1[0m
[1m[35mSQL (15.6ms)[0m UPDATE "locations" SET "short_desc" = $1, "meats_beef" = $2, "meats_pork" = $3, "meats_beef_ribs" = $4, "meats_pork_ribs" = $5, "meats_chicken" = $6, "meats_turkey" = $7, "meats_sausage" = $8, "meats_venison" = $9, "sauce" = $10, "latitude" = $11, "updated_at" = $12 WHERE "locations"."id" = $13 [["short_desc", "A Texan, Ms. Diana has been cookin' up barbecue for 50 years and, spreadin' the “barbecue love” in Paris (France!) since 2010."], ["meats_beef", "f"], ["meats_pork", "f"], ["meats_beef_ribs", "f"], ["meats_pork_ribs", "f"], ["meats_chicken", "f"], ["meats_turkey", "f"], ["meats_sausage", "f"], ["meats_venison", "f"], ["sauce", "f"], ["latitude", 48.13340729999999], ["updated_at", "2015-07-20 13:04:30.437500"], ["id", 46]]
[1m[36m (46.9ms)[0m [1mCOMMIT[0m
我想如果:选项为什么只在创建时验证唯一性?您还可以显示您的
用户控制器吗,特别是user\u params
强参数方法?如果:
选项为什么只在创建时验证唯一性,我想您必须使用reject\u?您还可以显示您的user\u控制器
,特别是user\u params
强参数方法吗?让我试试您的建议。一个问题,我是否也必须更改表格?我正在使用用户
表单。我是否必须建立一个人
人?是的。将表单中的逻辑翻转到person/user而不是user/person。有一点,您发布的表单示例没有提交/按钮,因此我假设您在示例中故意忽略了这一点。或者,您是否仅将表单用于显示?嗯,它适用于我在所属的上嵌套属性!我使用的是Mongoid而不是ActiveRecord,但我不明白为什么会有问题?@CyrilDD我不知道Mongoid。可能不同,因为它不使用活动记录。根据轨道规范w/Act。记录嵌套属性。关系仅通过父母与子女之间的关系发挥作用。如果你看到相反的做法成功的话,我当然愿意改变我的立场。让我试试你的建议。一个问题,我是否也必须更改表格?我正在使用用户
表单。我是否必须建立一个人
人?是的。将表单中的逻辑翻转到person/user而不是user/person。有一点,您发布的表单示例没有提交/按钮,因此我假设您在示例中故意忽略了这一点。或者,您是否仅将表单用于显示?嗯,它适用于我在所属的上嵌套属性!我使用的是Mongoid而不是ActiveRecord,但我不明白为什么会有问题?@CyrilDD我不知道Mongoid。可能不同,因为它不使用活动记录。根据轨道规范w/Act。记录嵌套属性。关系仅通过父母与子女之间的关系发挥作用。如果你已经看到相反的成功,我当然愿意改变我的立场。