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

Incoherent validation with nested_attributes for belongs_to associations #36581

Closed
marciojg opened this issue Jul 1, 2019 · 4 comments · Fixed by #36671
Closed

Incoherent validation with nested_attributes for belongs_to associations #36581

marciojg opened this issue Jul 1, 2019 · 4 comments · Fixed by #36671

Comments

@marciojg
Copy link

marciojg commented Jul 1, 2019

Steps to reproduce

Execute this code and you can see that the L68, L69 lines return different values.

Expected behavior

Returns true to L68, L69

Actual behavior

Incoherent and insistent values are returned. And the validation error presented is from the person object (L70)

System configuration

Rails version: 5.2.3

Ruby version: 2.6.3

@pedrofurtado
Copy link
Member

pedrofurtado commented Jul 5, 2019

@WillRadi @rafaelfranca

@pedrofurtado
Copy link
Member

Any news about this issue?

@wjessop
Copy link
Contributor

wjessop commented Jul 12, 2019

Replicated with Rails head (currently 356857a) and sqlite3 v1.4.1

@wjessop
Copy link
Contributor

wjessop commented Jul 13, 2019

This can be expressed with some simpler repro code:

class Matriculation < ActiveRecord::Base
  belongs_to :person

  accepts_nested_attributes_for :person
end

class Person < ActiveRecord::Base
  has_many :matriculations, autosave: true
  validates :name, presence: true
end

class BugTest < Minitest::Test
  def test_case
    person = Person.create!(name: 'Jhon')
    Matriculation.create!(person: person)

    person.name = nil
    person.save! validate: false # In this moment the object person is invalid. But matriculation isn't.

    matriculation = Matriculation.first

    assert_equal true, matriculation.valid? # First call
    assert_equal true, matriculation.person.present?
    assert_equal false, matriculation.valid? # Second call, return changed??? What?
  end
end

I think the issue is that when the first matriculation.valid? is called, the person association hasn't been loaded, and so isn't validated. When matriculation.person.present? is called, the person class is loaded, the validation callback is registered, and subsequent calls to matriculation.valid? will run the Person validation too.

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

Successfully merging a pull request may close this issue.

3 participants