-
Notifications
You must be signed in to change notification settings - Fork 403
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
Nested simple_fields_for
no longer inherits validate: true
(since v4.2.5)
#680
Comments
Doesn't work for me with 4.2.0+ neither. I'm investigating Gemfile: gem 'client_side_validations'
gem 'rails', '4.2.7.1' User Model class User < ActiveRecord::Base
has_one :address
end Address model class Address < ActiveRecord::Base
belongs_to :user
validates :street, presence: true
end erb <%= simple_form_for @user, validate: true do |f| %>
<%= f.simple_fields_for :address do |address| %>
<%= address.input :street %>
<% end %>
<% end %> output html <form data-validate="true" novalidate="novalidate" class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="fqlMT7YMfgk5RWPMi38krHHmB8lFE7JlhX+w1Ja2eu0iyP6CUPZrvVzBTkVQIl/q6X3BmYDTMn4u5P30aQwqLQ==" />
<input type="text" name="user[address][street]" id="user_address_street" />
</form><script>
//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=["uniqueness"];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_user'] = {"type":"ActionView::Helpers::FormBuilder","input_tag":"\u003cdiv class=\"field_with_errors\"\u003e\u003cspan id=\"input_tag\" /\u003e\u003c/div\u003e","label_tag":"\u003cdiv class=\"field_with_errors\"\u003e\u003clabel id=\"label_tag\" /\u003e\u003c/div\u003e","validators":{}};
//]]>
</script> The problem is that tests for |
Thank you for looking into this, @tagliala. |
The problem is that Hope it helps |
The problem is still present in the latest version ( |
Problem is that I cannot replicate on older versions If you think there is a regression in a specific version (eg: 4.2.4 works, 4.2.5 doesn't), please write a failing test case and use git bisect to find the offending commit |
Hi @tagliala, I finally took the time to git-bisect this puppy. Luckily the offending commit is quite small: 77799b3. I also found out that it is enough to reverse def fields_for_with_client_side_validations(record_name, record_object = nil, fields_options = {}, &block)
fields_options[:validate] ||= @options[:validate] if @options[:validate] && !fields_options.key?(:validate)
fields_for_without_client_side_validations(record_name, record_object, fields_options, &block)
end to def fields_for_with_client_side_validations(record_or_name_or_array, *args, &block)
options = args.extract_options!
options[:validate] ||= @options[:validate] if @options[:validate] && !options.key?(:validate)
fields_for_without_client_side_validations(record_or_name_or_array, *(args << options), &block)
end get rid of the problem. This got me all excited and I tried to debug what is happening here some more, but this is deep into the FormBuilder stuff and I am having trouble understanding what is going on. I did however also see that there is a fallback in rails (v4.2) for the old arguments notation:
so #665 is not necessary for def fields_for_with_client_side_validations(record_name, record_object = nil, fields_options = {}, &block)
fields_options[:validate] ||= @options[:validate] if @options[:validate] && !fields_options.key?(:validate)
fields_for_without_client_side_validations(record_name, *([] << fields_options), &block)
end also fixes the problem for our use case. Let me know, if any of this makes sense to you and I would be very interested to here where I need to dig deeper to finally get to the bottom of this. Thank you very much for your time. |
@janraasch thanks for your effort. The problem is that I still cannot replicate this issue. I can't see a regression from 4.2.4 to 4.2.5. I would like to see a failing test case, otherwise I cannot help Modelsclass User < ActiveRecord::Base
has_one :address
end
class Address < ActiveRecord::Base
belongs_to :user
validates :street, presence: true
end Controllerclass UsersController < ApplicationController
def new
@user = User.new
end
end View<%- require 'client_side_validations/version' %>
CSV Version: <%= ClientSideValidations::VERSION %>
<%= simple_form_for @user, validate: true do |f| %>
<%= f.simple_fields_for :address do |address| %>
<%= address.input :street %>
<% end %>
<% end %> Output (CSV 4.2.4)CSV Version: 4.2.4
<form data-validate="true" novalidate="novalidate" class="simple_form new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="hGKezNyzaS0/lEBf3xFdKVfDXoVkQcbRabHWvcljWmXYAywBOkl8mVoQbdYETCZvz1iY1aGBRsrCKpudNtkKpQ==" />
<div class="input string required user_address_street"><label class="string required" for="user_address_street"><abbr title="required">*</abbr> Street</label><input class="string required" type="text" name="user[address][street]" id="user_address_street" /></div>
</form><script>//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=[];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_user'] = {"type":"SimpleForm::FormBuilder","input_tag":"\u003cspan id=\"input_tag\" /\u003e","label_tag":"\u003clabel id=\"label_tag\" /\u003e","validators":{}};
//]]></script> Output (CSV 4.2.5)CSV Version: 4.2.5
<form data-validate="true" novalidate="novalidate" class="simple_form new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="t45bUGJmMaHlod+HTCu+oD2XFIm6elI7SxSs58T0Bx3r7+mdhJwkFYAl8g6XdsXmpQzS2X+60iDgj+HHO05X3Q==" />
<div class="input string required user_address_street"><label class="string required" for="user_address_street"><abbr title="required">*</abbr> Street</label><input class="string required" type="text" name="user[address][street]" id="user_address_street" /></div>
</form><script>
//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=[];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_user'] = {"type":"SimpleForm::FormBuilder","input_tag":"\u003cspan id=\"input_tag\" /\u003e","label_tag":"\u003clabel id=\"label_tag\" /\u003e","validators":{}};
//]]>
</script> |
btw I could definitely see that something may go wrong when fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options? will overwrite the actual |
So now I have at least produced a working example you can have a look at. The code is basically as you suggested: Modelsclass User < ActiveRecord::Base
belongs_to :company
validates :first_name, presence: true
validates :last_name, presence: true
accepts_nested_attributes_for :company
end
class Company < ActiveRecord::Base
validates :name, presence: true
end Notice the Controllerclass UsersController < ApplicationController
def new
@user = User.new
@user.build_company
end
end View<%- require 'client_side_validations/version' %>
CSV Version: <%= ClientSideValidations::VERSION %>
<%= simple_form_for @user, method: :post, validate: true do |f| %>
<%= f.input :first_name %>
<%= f.input :last_name %>
<%= f.simple_fields_for :company do |company_form| %>
<%= company_form.input :name %>
<% end %>
<%= f.button :submit %>
<% end %> Output (CSV 4.2.4)<body>
CSV Version: 4.2.4
<form data-validate="true" novalidate="novalidate" class="simple_form new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="FZLVBXFyXJ3KoJFGnTDJ3Gi/Zrka5szbL3h29daWFTKkI6XRXucz+Es1OEb3I8PNoWSgYPv3ZDPDzTdgoEBYEQ==">
<div class="input string required user_first_name"><label class="string required" for="user_first_name"><abbr title="required">*</abbr> First name</label><input class="string required" required="required" aria-required="true" type="text" name="user[first_name]" id="user_first_name"></div>
<div class="input string required user_last_name"><label class="string required" for="user_last_name"><abbr title="required">*</abbr> Last name</label><input class="string required" required="required" aria-required="true" type="text" name="user[last_name]" id="user_last_name"></div>
<div class="input string required user_company_name"><label class="string required" for="user_company_attributes_name"><abbr title="required">*</abbr> Name</label><input class="string required" required="required" aria-required="true" type="text" name="user[company_attributes][name]" id="user_company_attributes_name"></div>
<input type="submit" name="commit" value="Create User" class="button">
</form><script>//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=["uniqueness"];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_user'] = {"type":"SimpleForm::FormBuilder","error_class":"error","error_tag":"span","wrapper_error_class":"field_with_errors","wrapper_tag":"div","wrapper_class":"input","wrapper":"default","validators":{"user[company_attributes][name]":{"presence":[{"message":"can't be blank"}]},"user[first_name]":{"presence":[{"message":"can't be blank"}]},"user[last_name]":{"presence":[{"message":"can't be blank"}]}}};
//]]></script>
</body> To reproduce this locally you may check out https://github.com/janraasch/client_side_validations_debugging/commit/520636625fe82704fa2814c10c796c66ffe038c0. Output (CSV 4.2.5)<body>
CSV Version: 4.2.5
<form data-validate="true" novalidate="novalidate" class="simple_form new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="lCrwNh7IvHn1b7+FJQ1sxCigmyFkET102JpJyZkol28lm4DiMV3THHT6FoVPHmbV4Xtd+IUAlZw0Lwhc7/7aTA==">
<div class="input string required user_first_name"><label class="string required" for="user_first_name"><abbr title="required">*</abbr> First name</label><input class="string required" required="required" aria-required="true" type="text" name="user[first_name]" id="user_first_name"></div>
<div class="input string required user_last_name"><label class="string required" for="user_last_name"><abbr title="required">*</abbr> Last name</label><input class="string required" required="required" aria-required="true" type="text" name="user[last_name]" id="user_last_name"></div>
<div class="input string required user_company_name"><label class="string required" for="user_company_attributes_name"><abbr title="required">*</abbr> Name</label><input class="string required" required="required" aria-required="true" type="text" name="user[company_attributes][name]" id="user_company_attributes_name"></div>
<input type="submit" name="commit" value="Create User" class="button">
</form><script>
//<![CDATA[
if(window.ClientSideValidations===undefined)window.ClientSideValidations={};window.ClientSideValidations.disabled_validators=["uniqueness"];window.ClientSideValidations.number_format={"separator":".","delimiter":","};if(window.ClientSideValidations.patterns===undefined)window.ClientSideValidations.patterns = {};window.ClientSideValidations.patterns.numericality=/^(-|\+)?(?:\d+|\d{1,3}(?:\,\d{3})+)(?:\.\d*)?$/;if(window.ClientSideValidations.forms===undefined)window.ClientSideValidations.forms={};window.ClientSideValidations.forms['new_user'] = {"type":"SimpleForm::FormBuilder","error_class":"error","error_tag":"span","wrapper_error_class":"field_with_errors","wrapper_tag":"div","wrapper_class":"input","wrapper":"default","validators":{"user[first_name]":{"presence":[{"message":"can't be blank"}]},"user[last_name]":{"presence":[{"message":"can't be blank"}]}}};
//]]>
</script>
</body> To reproduce this locally you may check out https://github.com/janraasch/client_side_validations_debugging/commit/e9e54941a81d39058a03d887f8e1df23d34d67b8. Comparing the script tagsAs you can see, there is no entry of To reproduce this on your machine, please use the code I provided on https://github.com/janraasch/client_side_validations_debugging. I simply generated a rails app and added the models, controllers and views as described above. You simply need to checkout the repository. Run |
FYI. I added a |
I was going to just remove the simple_form dependency to check this issue. So we are in the wrong repo and I should add a failing test to CSV-simple_form |
Yo! |
Yo? :)
That is for you to decide. So far I have been unable to reproduce this in a unit test. The issue is definitely because of the
business I mentioned earlier. This |
please add fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options? before fields_options[:validate] ||= @options[:validate] if @options[:validate] && !fields_options.key?(:validate) and it should do the job. I'm trying to write a failing spec on CSV-simple_form and fix this in CSV |
Starting from v4.2.5, fields_for has been suffering from a regression when the record_object passed to the form was a hash. This is particularly true with simple_form and has_one nested models. Fix: #680
@janraasch I was been finally able to reproduce the issue inside a spec and fix that Thanks for your effort I'm going to release 9.3.2 tomorrow, but I don't know if I will backport this to the 4.2 branch |
Having a working version of |
It should avoid reintroducing an issue with simple_fields_for in the future. Ref: DavyJonesLocker/client_side_validations#680
@janraasch thanks for being so patient, it really took a lot of time to understand what was going on. I've just released CSV 9.3.2 and CSV-simple_form 6.3.0. The issue has been fixed in CSV, so you should be fine by just updating the CSV gem. I took the opportunity to release CSV-simple_form 6.3.0 which contains another spec to test |
Hi there,
we have a
simple_fields_for
call inside asimple_form_for
-form withvalidate: true
passed to the form. Beforev4.2.5
the required nestedsimple_fields_for
attributes would be added to the@validators
automatically.Example
Say we have a
User
model and anAddress
model. Now, theAddress
requires astreet
, and theUser
of course has anaddress
.A sign-up form for a
User
thus would look like the followingExpected Behavior
Before
v4.2.5
this would cause thestreet
-Input to be validated on the client-side. As ofv4.2.5
thestreet
-Input is not validated on the client-side.Temporary Fix
This can be fixed by adding
validate: true
to theuser.simple_fields_for :address
call.Versions
Works as expected on
v4.2.4
. Breaks on all later versions, includingv4.2.7
. We are runningclient_side_validations-simple_form v3.2.4
, and upgrading tov3.3.0
also does not help; which is why I suspect the problem to originate fromclient_side_validations
itself.Supposedly this is a regression, or it is a breaking change which should have been part of a major update.
Let me know, if you need more information.
The text was updated successfully, but these errors were encountered: