Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error does not bubble up from duplicate associated record #32940

Closed
Mangara opened this issue May 20, 2018 · 1 comment
Closed

Error does not bubble up from duplicate associated record #32940

Mangara opened this issue May 20, 2018 · 1 comment

Comments

@Mangara
Copy link
Contributor

Mangara commented May 20, 2018

Steps to reproduce

Models:

class Parent < ApplicationRecord
  has_many :children
end

class Child < ApplicationRecord
  belongs_to :parent
  validates :name, uniqueness: true
end

Code:

parent = Parent.new(children: [Child.new(name: 'Wiske'), Child.new(name: 'Wiske')])
parent.save
parent.errors.any?

Executable test

Expected behavior

The children are invalid, so there should be an error on parent.

Actual behavior

There is no error on parent, only on the second child:

parent = Parent.new(children: [Child.new(name: 'Wiske'), Child.new(name: 'Wiske')])
parent.valid? # true
  # Child Exists (0.6ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
  # Child Exists (0.5ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
parent.save # true
  #  (0.6ms)  BEGIN
  # Child Exists (0.6ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
  # Child Exists (0.5ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
  # Parent Create (0.5ms)  INSERT INTO `parents` (`created_at`, `updated_at`) VALUES ('2018-05-20 19:14:06', '2018-05-20 19:14:06')
  # Child Exists (0.6ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
  # Child Create (7.2ms)  INSERT INTO `children` (`name`, `parent_id`) VALUES ('Wiske', 5)
  # Child Exists (0.6ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
  #  (2.8ms)  COMMIT
parent.errors.any? # false
parent.children # [#<Child id: 6, name: "Wiske", parent_id: 5>, #<Child id: nil, name: "Wiske", parent_id: 5>]
parent.children[1].errors.any? # true
parent.children[1].errors.full_messages # ["Name has already been taken"]
parent.valid? # false
  # Child Exists (0.7ms)  SELECT  1 AS one FROM `children` WHERE `children`.`name` = BINARY 'Wiske' LIMIT 1
parent.errors.any? # true
parent.errors.full_messages # ["Children is invalid"]

Since there are no uniqueness problems between each child individually and what's already in the database, validation of the parent passes. Each child is revalidated before being saved, so when the second child is saved, the duplication is detected and an error is added to the child model. However, this error does not propagate to the parent as typically happens with validation errors.

System configuration

Rails version: 5.2.0

Ruby version: 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]

(See also #32939)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants