I am just getting started with Rails, don''t know any Ruby, and don''t quite even get object oriented programming yet. I have tweaked my schema to The Rails Way and have generated a bit of scaffolding. I am trying to create a new Part, which references a PartName and a PartNumber. I can create a PartNumber on the fly, but the PartName has to exist. I have an inelegant solution that works, but does not properly exploit the validation because I don''t get back the appropriate errors when a PartName is not existent or a PartNumber fails to be created. All I get is that the Part was missing the key values. Is there a simpler way to design the :create such that the referenced records will be created if they don''t exist (or fail if they don''t exist in the case of PartName) and return relevant error information to the user? I know this is all wrong, but would love a few pointers on the right way to do it!! Thank you in advance... - Ian -----------------Schema ------------------ CREATE TABLE part_names ( id serial primary key, part_name character varying NOT NULL, group_id integer not null, description character varying, idx_part_name tsvector ); ALTER TABLE part_names ADD CONSTRAINT pn_group FOREIGN KEY (group_id) REFERENCES groups(id) DEFERRABLE INITIALLY DEFERRED; CREATE TABLE part_numbers ( id serial primary key, part_number integer NOT NULL, constraint chk_part_number check (part_number ~''[0-9]*'') ); CREATE TABLE parts ( id serial primary key, part_number_id integer NOT NULL, part_name_id integer NOT NULL, quantity integer DEFAULT 1 NOT NULL, side character varying, size character varying, "comment" character varying, constraint chk_side check (side in (''L.H.'', ''R.H.'') or side is null) ); ALTER TABLE parts ADD CONSTRAINT parts_pnumber_fkey FOREIGN KEY (part_number_id) REFERENCES part_numbers(id) DEFERRABLE INITIALLY DEFERRED; ALTER TABLE parts ADD CONSTRAINT parts_pname_fkey FOREIGN KEY (part_name_id) REFERENCES part_names(id) DEFERRABLE INITIALLY DEFERRED; ---------------------Models-------------------- class Part < ActiveRecord::Base belongs_to :part_name belongs_to :part_number has_many :part_years has_many :part_details has_many :part_comments has_many :car_job_parts validates_inclusion_of :side, :allow_nil => true, :in => %w{ L.H. R.H. } validates_inclusion_of :quantity, :in => 1..99 validates_presence_of :part_number_id, :part_name_id validates_associated :part_number, :part_name validates_uniqueness_of :part_number_id, :scope => "part_name_id" end class PartNumber < ActiveRecord::Base has_many :parts has_many :part_number_images has_many :part_number_illustrations has_and_belongs_to_many :vendor_parts validates_numericality_of :part_number validates_inclusion_of :part_number, :in => 111111..99999999 validates_uniqueness_of :part_number end class PartName < ActiveRecord::Base belongs_to :group has_and_belongs_to_many :jobs has_many :parts validates_presence_of :part_name, :group_id # validates_associated :groups <-- causes infinite loop! validates_associated :parts validates_uniqueness_of :part_name end ---------------------View --------------------- _form.html <%= error_messages_for ''part'' %> <!--[form:part]--> <p><label for="part_name">Part Name</label><br/> <%= text_field_with_auto_complete :part_name, :part_name %> <p><label for="part_number">Part Number</label><br/> <%= text_field_with_auto_complete :part_number, :part_number %> <p><label for="part_quantity">Quantity</label><br/> <%= text_field ''part'', ''quantity'' %></p> <p><label for="part_side">Side</label><br/> <%= text_field ''part'', ''side'' %></p> <p><label for="part_size">Size</label><br/> <%= text_field ''part'', ''size'' %></p> <p><label for="part_comment">Comment</label><br/> <%= text_field_with_auto_complete :part, :comment %> <!--[eoform:part]--> -------------------Controller--------------------------- class PartsController < ApplicationController auto_complete_for :part, :comment auto_complete_for :part_number, :part_number auto_complete_for :part_name, :part_name def index list render :action => ''list'' end def list @part_pages, @parts = paginate :parts, :order => "part_name_id", :per_page => 10 end def show @part = Part.find(params[:id]) end def new @part = Part.new @part_name = PartName.new @part_number = PartNumber.new end def create @part = Part.new(params[:part]) @part_name = PartName.new(params[:part_name]) @part_number = PartNumber.new(params[:part_number]) # I dont want to create a part name because there is more to it than this # but I want creation to fail. It does, but the field is not highlighted # because the object is not specifically invalidated? @part.part_name = PartName.find_by_part_name(params[:part_name][:part_name]) # The find portion of this seems to try to find the record, regardless of whether # the input is of the wrong type. I suppose that makes sense, but there must # be an easier way than explicitly calling .valid? if @part_number.valid? @part.part_number PartNumber.find_or_create_by_part_number(params[:part_number][:part_number]) end if @part.save flash[:notice] = ''Part was successfully created.'' redirect_to :action => ''list'' else render :action => ''new'' end end def edit @part = Part.find(params[:id]) end def update @part = Part.find(params[:id]) if @part.update_attributes(params[:part]) flash[:notice] = ''Part was successfully updated.'' redirect_to :action => ''show'', :id => @part else render :action => ''edit'' end end def destroy Part.find(params[:id]).destroy redirect_to :action => ''list'' end end