hi I am facing a problem. I have two models A and B which have relations as follows A has_one B B belongs_to A Now I want to ensure that whenever an ''A'' record is created, automatically a ''B'' record is also created. I was trying to achieve this by doing the following but it is not making the entry in B table, otherwise code runs fine without any errors. what can be the reason. ?? class AController < ApplicationController def create @a = A.new(params[:a]) respond_to do |:a| if @a.save ##### NEW CODE - THIS IS WHAT I HAVE ADDED @b = B.new @b.a_id = @a.id @b.save #### NEW CODE END flash[:notice] = ''A was successfully created.'' format.html { redirect_to(@a) } format.xml { render :xml => @a, :status => :created, :location => @a } else formatat.html { render :action => "new" } format.xml { render :xml => @a.errors, :status => :unprocessable_entity } end end end end vipin
I wonder if @b.save is returning false? Maybe a validation issue? Have you tried throwing a debugger statement in there? On May 28, 7:09 am, Vipin <sh.vi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> hi > I am facing a problem. I have two models A and B which have relations > as follows > > A has_one B > B belongs_to A > > Now I want to ensure that whenever an ''A'' record is created, > automatically a ''B'' record is also created. > I was trying to achieve this by doing the following but it is not > making the entry in B table, otherwise code runs fine without any > errors. > > what can be the reason. ?? > > class AController < ApplicationController > > def create > @a = A.new(params[:a]) > > respond_to do |:a| > if @a.save > ##### NEW CODE - THIS IS WHAT I HAVE ADDED > @b = B.new > @b.a_id = @a.id > @b.save > #### NEW CODE END > > flash[:notice] = ''A was successfully created.'' > format.html { redirect_to(@a) } > format.xml { render :xml => @a, :status > => :created, :location => @a } > else > formatat.html { render :action => "new" } > format.xml { render :xml => @a.errors, :status > => :unprocessable_entity } > end > end > end > > end > > vipin
Vipin, wouldn''t it be better moving this out of the controller altogether? If every A should have a B then I''d create an observer - "AObserver" and add an after_create callback: class AObserver < ActiveRecord::Observer def after_create(a) B.create! :a_id => a.id end end
Yeah, it really belongs in the model... On May 28, 9:42 am, Gavin <ga...-YMj/zd8x6QpKMzDMP321V2ksYUyLi9NM@public.gmane.org> wrote:> Vipin, > > wouldn''t it be better moving this out of the controller altogether? > > If every A should have a B then I''d create an observer - "AObserver" > > and add an after_create callback: > > class AObserver < ActiveRecord::Observer > > def after_create(a) > B.create! :a_id => a.id > end > end
On May 28, 6:02 pm, tomrossi7 <t...-5bxIUPmzHicFraO2wh7vUA@public.gmane.org> wrote:> I wonder if @b.save is returning false? Maybe a validation issue? > Have you tried throwing a debugger statement in there? >yea it turned out to be exactly the ''save'' failure due to validation. thanks....
I would go with the observer so you can keep the logic in the model (observer)...skinny controllers, fat models and all. http://guides.rails.info/activerecord_validations_callbacks.html#observers
On May 28, 6:42 pm, Gavin <ga...-YMj/zd8x6QpKMzDMP321V2ksYUyLi9NM@public.gmane.org> wrote:> Vipin, > > wouldn''t it be better moving this out of the controller altogether? > > If every A should have a B then I''d create an observer - "AObserver" > > and add an after_create callback: > > class AObserver < ActiveRecord::Observer > > def after_create(a) > B.create! :a_id => a.id > end > endbut won''t t also have the issue of validation.
yes and no after_create is called after A has been saved, so it will be valid. You''ll have to make sure that the params for B are valid though By calling create! instead of create, rails will raise an exception if B is not valid but you could also write; after_create(a) B.create :a_id => a.id if a.b # => tests if a now has a valid B return true else # if it could not create B [do something here] end end Perhaps if you give us a little more information on A and B, their attributes etc., I can offer a little more advice? G On May 28, 4:05 pm, Vipin <sh.vi...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On May 28, 6:42 pm, Gavin <ga...-YMj/zd8x6QpKMzDMP321V2ksYUyLi9NM@public.gmane.org> wrote: > > > Vipin, > > > wouldn''t it be better moving this out of the controller altogether? > > > If every A should have a B then I''d create an observer - "AObserver" > > > and add an after_create callback: > > > class AObserver < ActiveRecord::Observer > > > def after_create(a) > > B.create! :a_id => a.id > > end > > end > > but won''t t also have the issue of validation.
> Perhaps if you give us a little more information on A and B, their > attributes etc., I can offer a little more advice? >Well, what I am trying to achieve here is that no way two records are created in B such that they belong to same record in A. For clear explanation let me try to map the problem in more realistic way. Let''s say A => Student {roll_no} B => Marksheet ( maths, science, sst, student_id ) Now every student has only one marksheet. I want to make sure that for every student only one mark sheet is created. For this I have maintained a relationship of 1:1 between STudent:Marksheet. Marksheet blongs_to Student and Student has_one marksheet. Marksheet also has a field student_id. And <<<<validates_uniqueness_of :student_id >>.>>will ensure that no two records are created in a normal situation. But I am concerned of a rare possibility when through two different sessions same user is trying to create two marksheets. Based on my understanding in such cases, this validation might allow to create two records with the same "stident_id" if in both the sessions database is fetched when no record was saved. My approach was to not even to let the user create the record in Marksheet/ As soon as a Student record is created, I add the Marksheet record as well. Now I can create and save marksheet record in normal case but if Marksheet record has validations for NIL fields ( to be left NIL initially for subject fields ) will fail the validation. Is it the situation where "locks" are used ?? vipin