Hello, I have a form that submits data to two related models/tables. One is Customer the other is Address. Validation for Customer works fine but not for the Address. Class Customer < ActiveRecord::Base has_one :address validates_presence_of :login, :password, :email validates_associated :address end Class Address < ActiveRecord::Base belongs_to :customer validates_presence_of :address1, :city, :state, :zip end With the code below the validation simply doesn''t work and the address object doesn''t get saved if all the required fields are empty. def signup @customer = Customer.new(params[:customer]) @address = Address.new(params[:customer]) if @customer.save @customer.address = @address redirect_to : action => ''login'' end End If I move the line: @customer.address = @address before the @customer.save then ''validates_associated'' works (it responds with ''address is invalid'') but nothing gets saved to address the table. Any suggestions? Sergio
Associated models only get validates on save. The issue is that you did not associate address before you save customer so Rails as no way of figuring out what it should validate. So either you associate and then you save (and validate everything in the same process), or you validate and save both models separately (and you have to do the mapping yourself with @address.customer_id = @customer.id before you save @address).>I have a form that submits data to two related models/tables. One is >Customer the other is Address. Validation for Customer works fine but not >for the Address. > >Class Customer < ActiveRecord::Base >has_one :address > validates_presence_of :login, :password, :email > validates_associated :address >end > >Class Address < ActiveRecord::Base > belongs_to :customer > validates_presence_of :address1, :city, :state, :zip >end > >With the code below the validation simply doesn''t work and the address >object doesn''t get saved if all the required fields are empty. > >def signup > @customer = Customer.new(params[:customer]) > @address = Address.new(params[:customer]) > if @customer.save > @customer.address = @address > redirect_to : action => ''login'' > end >End > >If I move the line: >@customer.address = @address >before the @customer.save then ''validates_associated'' works (it responds >with ''address is invalid'') but nothing gets saved to address the table. > >Any suggestions? > >
Wilson Bilkovich
2005-Oct-12 20:23 UTC
Re: Validating 2 related models at once not working
How about this? Not the tersest way to write it, but hopefully it explains what''s going on. validates_associated is more helpful when you''re associating something that''s already been created. When you''re making both objects at the same time, and they don''t have id numbers yet, you have to do some more hand-holding. def signup @customer = Customer.new(params[:customer]) @address = Address.new(params[:customer]) if @address.valid? @customer.address = @address # Assigning @address to the association will save it, but that only works if it''s valid. # Another way would be to skip the Address.new above, and do: # @customer.build_address(params[:customer]) else # Send the user somewhere here, because the address provided is busted. end if @customer.save redirect_to : action => ''login'' end end On 10/12/05, Sergio Bayona <sergio-SZhfuDltjDxEfCMKe0UOsQC/G2K4zDHf@public.gmane.org> wrote:> Hello, > > I have a form that submits data to two related models/tables. One is > Customer the other is Address. Validation for Customer works fine but not > for the Address. > > Class Customer < ActiveRecord::Base > has_one :address > validates_presence_of :login, :password, :email > validates_associated :address > end > > Class Address < ActiveRecord::Base > belongs_to :customer > validates_presence_of :address1, :city, :state, :zip > end > > With the code below the validation simply doesn''t work and the address > object doesn''t get saved if all the required fields are empty. > > def signup > @customer = Customer.new(params[:customer]) > @address = Address.new(params[:customer]) > if @customer.save > @customer.address = @address > redirect_to : action => ''login'' > end > End > > If I move the line: > @customer.address = @address > before the @customer.save then ''validates_associated'' works (it responds > with ''address is invalid'') but nothing gets saved to address the table. > > Any suggestions? > > Sergio > > > > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
You are right and I did do @customer.address = @address before save, in theory this it should associate address to customer. That triggered an address validation error when invalid, but when the address was valid it didn''t save it on the database. On 10/12/05 1:16 PM, "Jos" <jos-opYYzZorcyRWk0Htik3J/w@public.gmane.org> wrote:> Associated models only get validates on save. The issue is that you did > not associate address before you save customer so Rails as no way of > figuring out what it should validate. > > So either you associate and then you save (and validate everything in > the same process), or you validate and save both models separately (and > you have to do the mapping yourself with @address.customer_id > @customer.id before you save @address). > >> I have a form that submits data to two related models/tables. One is >> Customer the other is Address. Validation for Customer works fine but not >> for the Address. >> >> Class Customer < ActiveRecord::Base >> has_one :address >> validates_presence_of :login, :password, :email >> validates_associated :address >> end >> >> Class Address < ActiveRecord::Base >> belongs_to :customer >> validates_presence_of :address1, :city, :state, :zip >> end >> >> With the code below the validation simply doesn''t work and the address >> object doesn''t get saved if all the required fields are empty. >> >> def signup >> @customer = Customer.new(params[:customer]) >> @address = Address.new(params[:customer]) >> if @customer.save >> @customer.address = @address >> redirect_to : action => ''login'' >> end >> End >> >> If I move the line: >> @customer.address = @address >> before the @customer.save then ''validates_associated'' works (it responds >> with ''address is invalid'') but nothing gets saved to address the table. >> >> Any suggestions? >> >> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails
The code below does trigger validation on both models but it doesn''t save Address on the db. Why is that? def signup @customer = Customer.new(params[:customer]) @address = Address.new(params[:customer]) @customer.address = @address if @customer.save redirect_to : action => ''login'' end End On 10/12/05 1:16 PM, "Jos" <jos-opYYzZorcyRWk0Htik3J/w@public.gmane.org> wrote:> Associated models only get validates on save. The issue is that you did > not associate address before you save customer so Rails as no way of > figuring out what it should validate. > > So either you associate and then you save (and validate everything in > the same process), or you validate and save both models separately (and > you have to do the mapping yourself with @address.customer_id > @customer.id before you save @address). > >> I have a form that submits data to two related models/tables. One is >> Customer the other is Address. Validation for Customer works fine but not >> for the Address. >> >> Class Customer < ActiveRecord::Base >> has_one :address >> validates_presence_of :login, :password, :email >> validates_associated :address >> end >> >> Class Address < ActiveRecord::Base >> belongs_to :customer >> validates_presence_of :address1, :city, :state, :zip >> end >> >> With the code below the validation simply doesn''t work and the address >> object doesn''t get saved if all the required fields are empty. >> >> def signup >> @customer = Customer.new(params[:customer]) >> @address = Address.new(params[:customer]) >> if @customer.save >> @customer.address = @address >> redirect_to : action => ''login'' >> end >> End >> >> If I move the line: >> @customer.address = @address >> before the @customer.save then ''validates_associated'' works (it responds >> with ''address is invalid'') but nothing gets saved to address the table. >> >> Any suggestions? >> >> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails