An object that initializes multiple objects?


#1

Hi,

Something that I have noticed is that every class that inherits from
ActiveRecord::Base has a database table of its own.

However what if I don’t want a class to have its own table, but to
actually serve as a proxy to initialize other entries?

For instance as an example, let’s have a form with the fields for
“student name”, “student id number”, “parent’s name”, “street 1”,
“street 2”, “town”, “postcode”, “state”.

There will be (suppose) 2 underlying database tables that will be
populated as a result of this form submission, a table “student_record”
that has “id”, “name”, and “id_number” (not to be confused with “id”, it
is more like “passport number”), as well as another table “contact” with
the fields “parent_name”, “street_1”, “street_2”, “town”, “postcode”,
“state” as well as “student_record_id” which is a foreign key pointing
to the id of the associated “student_record”.

Now, strictly speaking it can be argued that all of these entries can be
put into a single table for simplicity’s sake, but supposing there are
students with multiple parental contacts (perhaps separated, or they
have holiday addresses, etc) and the system is meant to accomodate them,
hence the provision for multiple contacts.

How is it possible to have a “front end” class that acts and works just
like an object by itself (ie, maybe a “student” class), but actually
have no underlying database table of its own and instead exists by
pulling records from associated databases?


#2

I’m not sure if this matches what you need, but this is the first thing
that
popped in my head. So this means it’s probably more complicated than it
needs to be :slight_smile:

In the student model use:

class Student < ActiveRecord::Base
#this should handle the student_id reference as long as
#the contact table has a student_id field…
#but you can change this default association
#http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html#M000471
has_many :contact

…rest of model code
end

In the controller you can use:

def edit
@student = Student.find(@params[:student_id])
end

In the view you can use something like:
<%=text_field_tag(“student_name”,@student.name)%>

loop through the contacts:

<%
@student.contact.each{|contact|
%>
<%=text_field_tag(“street_#{contact.id}”,contact.street_1)%>
<%
}
%>

using the #{contact_id} to differentiate between the params.

any help at all?

-andy


#3

Thanks, that’s what I suspected too.

Initially I thought rails has a way of doing it so I can get something
for free, guess not :frowning:

Just to clear up something, so in the contact class there’d be a
statement belongs_to :student, and when I add a new contact to a student
I use the statement student.contact << Contact.new(:street1 => "etc
etc…)

Will I need to specify a :Student => student when creating the new
contact? Or will rails do that for free?


#4

I use the statement student.contact << Contact.new(:street1 => "etc
etc…)

I believe that using the above statement will handle student association
in
the new contact for you. I know this works for has_and_belongs_to_many,
just haven’t had the chance to use has_many yet.

-andy


#5

The trouble with using << is it seems like error messages that results
from a child object failing to save does not seem to show up to the
parent class. Is there a way to actually communicate the validation
error messages between the different .save methods?

I haven’t ran into this scenario, so I don’t have a well thought out
solution. Unless there’s a mechanism for this in Rails already, I would
think you would have to test for error messages after each save of the
child
and then add a message to the parent. There is probably a slick way to
do
this, but I don’t know it. :frowning:

-andy


#6

Andrew S. wrote:

I haven’t ran into this scenario, so I don’t have a well thought out
solution. Unless there’s a mechanism for this in Rails already, I would
think you would have to test for error messages after each save of the
child
and then add a message to the parent. There is probably a slick way to
do
this, but I don’t know it. :frowning:

-andy

Hmmm, but the flaw with that approach is that if you are calling .save
on a child object created via the append operator to a newly created
parent, it can only be saved when the parent is saved (the parent.id is
not present until it actually gets into the database).

Wonder if there is some way to override the default save behaviour?


#7

Andrew S. wrote:

I believe that using the above statement will handle student association
in
the new contact for you. I know this works for has_and_belongs_to_many,
just haven’t had the chance to use has_many yet.

-andy

Thanks Andrew, it does work :slight_smile:

However one issue that I have been trying to smooth out which is also
discussed at http://www.ruby-forum.com/topic/51957, let’s extend on our
example again and now this Contact class validates input postcodes by
matching them with the correct town and state names.

The trouble with using << is it seems like error messages that results
from a child object failing to save does not seem to show up to the
parent class. Is there a way to actually communicate the validation
error messages between the different .save methods?