You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi Daudi - many thanks for all of the work you have put into your milia gem! I have been trying to integrate 1.0.0-beta3 into my own project and hit an awkward issue that had me scratching my head for a couple of days and I think has highlighted an issue in the milia registrations controller and prep_signup_view code.
I was getting an ActiveModel::ForbiddenAttributesError error on my sign up form if hit submit whilst leaving the "Organisation Name" field blank (leaving the user fields blank was fine). When I ran your sample application I noticed that you don't have this issue (although your coupon field value becomes a hash for some reason - i'm leaving the coupon out so ignored this).
To cut a long painful story short, I had added a validation to my tenant model for the 'name' field: -
I think it reasonable to want to add some validation on the tenant to ensure uniqueness, presence and length etc. This leads to a problem in the milia registrations controller. If the tenant does not save properly then the form is re-displayed by your registration controller: -
Tenant.transactiondo@tenant=Tenant.create_new_tenant(sign_up_params_tenant,sign_up_params_coupon)if@tenant.errors.empty?# tenant createdinitiate_tenant(@tenant)# first time stuff for new tenantdevise_create# devise resource(user) creation; sets resourceifresource.errors.empty?# SUCCESS!# do any needed tenant initial setupTenant.tenant_signup(resource,@tenant,params[:coupon])else# user creation failed; force tenant rollbackraiseActiveRecord::Rollback# force the tenant transaction to be rolled back end# if..then..else for valid user creationelseprep_signup_view(@tenant,params[:user],params[:coupon])# PROBLEMrender:newend# if .. then .. else no tenant errors
By adding a validation on the tenant I caused the tenant save to fail we get sent through prep_signup_view before the form is re-rendered. You are passing the tenant object instance variable but passing the params[:user] hash. The params hash does not have any strong parameter whitelisting (permits etc.) on it and so causes the ForbiddenAttributesError when klass_option_obj calls 'new' on User using this hash.
Further down the controller you call prep_signup_view like this: -
This is great because it preps the form by using the permitted strong parameter versions of the parameters but has the downside that all error messages are lost. The errors are lost because prep_signup_view recreates the @user, @Tenant and @coupon instance variables as new from the params hashes.
I have tested this modification to the registration create method which fixes the strong parameter issue and makes sure that ALL validation errors are available to the form: -
defcreatesign_out_session!build_resource(sign_up_params)# added by daveprep_signup_view(sign_up_params_tenant,sign_up_params,sign_up_params_coupon)# added by dave# validate recaptcha first unless not enabledif !::Milia.use_recaptcha || verify_recaptchaTenant.transactiondo@tenant=Tenant.create_new_tenant(sign_up_params_tenant,sign_up_params_coupon)if@tenant.errors.empty?# tenant createdinitiate_tenant(@tenant)# first time stuff for new tenantdevise_create# devise resource(user) creation; sets resourceifresource.errors.empty?# SUCCESS!# do any needed tenant initial setupTenant.tenant_signup(resource,@tenant,params[:coupon])else# user creation failed; force tenant rollbackraiseActiveRecord::Rollback# force the tenant transaction to be rolled back end# if..then..else for valid user creationelseresource.valid?#prep_signup_view( @tenant, resource, sign_up_params_coupon ) # removed by daverender:newend# if .. then .. else no tenant errorsend# wrap tenant/user creation in a transactionelseflash[:error]="Recaptcha codes didn't match; please try again"resource.valid?@tenant.valid?#prep_signup_view( @tenant, resource, sign_up_params_coupon ) # removed by daverender:newendend# def create
By placing prep_signup_view at the top - it makes sure that all of the instance variables are created unless they already exist.
I needed to call devises build_resource function and the calls to valid? so that all form objects get validated, even if there are recaptcha errors or tenant problems. The form in your sample app doesn't appear to display any error messages.
One last change, it would be good to remember the tenant name even if there are errors with the user object validations, e.g. password_confirmation does not match. Instead of creating a new tenant form entry each time, you could use the existing one if already defined: -
This is a little ugly so it might be better to just use fields_for( @Tenant ) and add your prep_signup_view function to the devise controllers #new method (otherwise @Tenant will by nil the first time the form is called).
Thanks for having a look through my issue - I hope you will consider some of my suggestions! I do think that, as it stands, the sign_up form is broken if the tenant does not save properly (if someone innocently adds some simple validations to it!). I'm sure that a lot of people will be basing new applications on your sample application, so it would be very helpful if it it's able to display validation errors and remember the tenant and coupon fields successfully.
regards
Dave
The text was updated successfully, but these errors were encountered:
Oops - apologies, I had altered the prep_signup_view call when the re-captcha was not entered correctly; the version in your beta3 branch passes the non-whitelisted params hashes.
Hi Daudi - many thanks for all of the work you have put into your milia gem! I have been trying to integrate 1.0.0-beta3 into my own project and hit an awkward issue that had me scratching my head for a couple of days and I think has highlighted an issue in the milia registrations controller and prep_signup_view code.
I was getting an ActiveModel::ForbiddenAttributesError error on my sign up form if hit submit whilst leaving the "Organisation Name" field blank (leaving the user fields blank was fine). When I ran your sample application I noticed that you don't have this issue (although your coupon field value becomes a hash for some reason - i'm leaving the coupon out so ignored this).
To cut a long painful story short, I had added a validation to my tenant model for the 'name' field: -
I think it reasonable to want to add some validation on the tenant to ensure uniqueness, presence and length etc. This leads to a problem in the milia registrations controller. If the tenant does not save properly then the form is re-displayed by your registration controller: -
By adding a validation on the tenant I caused the tenant save to fail we get sent through prep_signup_view before the form is re-rendered. You are passing the tenant object instance variable but passing the params[:user] hash. The params hash does not have any strong parameter whitelisting (permits etc.) on it and so causes the ForbiddenAttributesError when klass_option_obj calls 'new' on User using this hash.
Further down the controller you call prep_signup_view like this: -
This is great because it preps the form by using the permitted strong parameter versions of the parameters but has the downside that all error messages are lost. The errors are lost because prep_signup_view recreates the @user, @Tenant and @coupon instance variables as new from the params hashes.
I have tested this modification to the registration create method which fixes the strong parameter issue and makes sure that ALL validation errors are available to the form: -
By placing prep_signup_view at the top - it makes sure that all of the instance variables are created unless they already exist.
I needed to call devises build_resource function and the calls to valid? so that all form objects get validated, even if there are recaptcha errors or tenant problems. The form in your sample app doesn't appear to display any error messages.
One last change, it would be good to remember the tenant name even if there are errors with the user object validations, e.g. password_confirmation does not match. Instead of creating a new tenant form entry each time, you could use the existing one if already defined: -
This is a little ugly so it might be better to just use fields_for( @Tenant ) and add your prep_signup_view function to the devise controllers #new method (otherwise @Tenant will by nil the first time the form is called).
Thanks for having a look through my issue - I hope you will consider some of my suggestions! I do think that, as it stands, the sign_up form is broken if the tenant does not save properly (if someone innocently adds some simple validations to it!). I'm sure that a lot of people will be basing new applications on your sample application, so it would be very helpful if it it's able to display validation errors and remember the tenant and coupon fields successfully.
regards
Dave
The text was updated successfully, but these errors were encountered: