Philip Nelson
2006-Sep-22 21:59 UTC
Linking tables with non-ID primary key / foreign key pair
Folks, I need to link two tables together which don''t conform to the standard Rails conventions (it doesn''t have an ID column as the primary key / foreign key column). I''ve got everything working for the COUNTRIES table (primary key COUNTRY_CODE), but can''t get the AIRPORTS table LIST function working (see error at bottom). Help please. Phil Here are the DB definitions (for migration) - ============== START OF DB DEFNS ==============================class CreateCountries < ActiveRecord::Migration def self.up create_table(:countries, :id => false, :options => '' IN SFPS001'') do |t| # t.column :name, :string t.column :country_code, :string, :null => false, :limit => 2 t.column :country_name, :string, :null => false, :limit => 50 end end def self.down drop_table :countries end end class CreateAirports < ActiveRecord::Migration def self.up create_table(:airports, :options => ''IN SFPS002'') do |t| # t.column :name, :string t.column :icao_code , :string, :null => false, :limit => 4 t.column :iata_code , :string, :null => false, :limit => 3 t.column :town , :string, :null => false, :limit => 100 t.column :state , :string, :limit => 100 t.column :airport_name, :string, :limit => 100 t.column :country_code, :string, :limit => 2 t.column :latitude , :float t.column :longitude , :float end execute "alter table dbfps001.airports add constraint r002001a foreign key (country_code) references dbfps001.countries (country_code) on delete restrict" end def self.down drop_table :airports end end ==================== END OF DB DEFNS ====================================== Here are the models I''ve defined - ==================== START OF MODELS ======================================class Country < ActiveRecord::Base primary_key :country_code has_many :trip_leg_passengers, :as => :passport_country has_many :airports, :as => :country_code validates_presence_of :country_code, :country_name validates_uniqueness_of :country_code validates_uniqueness_of :country_name end class Airport < ActiveRecord::Base has_many :trip_legs, :as => :start_airport has_many :trip_legs, :as => :end_airport belongs_to :country, :foreign_key => :country_code validates_presence_of :icao_code, :iata_code, :town validates_uniqueness_of :icao_code validates_uniqueness_of :iata_code end =================== END OF MODELS =============================== And here is the controller for Airports - ================== START OF CONTROLLERS =========================class AirportController < ApplicationController # # Enforce login # before_filter :authorize, :except => :login layout "admin" def index list render :action => ''list'' end # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update ], :redirect_to => { :action => :list } def list @airports = Airport.find(:all, :include => :country) end def show @airport = Airport.find(params[:id]) end def new @airport = Airport.new end def create @airport = Airport.new(params[:airport]) if @airport.save flash[:notice] = ''Airport was successfully created.'' redirect_to :action => ''list'' else render :action => ''new'' end end def edit @airport = Airport.find(params[:id], :include => :country) end def update @airport = Airport.find(params[:id], :include => :country) if @airport.update_attributes(params[:airport]) flash[:notice] = ''Airport was successfully updated.'' redirect_to :action => ''show'', :id => @airport else render :action => ''edit'' end end def destroy Airport.find(params[:id]).destroy redirect_to :action => ''list'' end end ================== END OF CONTROLLERS =========================== When I try to list the airport records I get - ============== START OF CUT ============================ActiveRecord::StatementInvalid: [IBM][CLI Driver][DB2/LINUX] SQL0206N "COUNTRIES.ID" is not valid in the context where it is used. SQLSTATE=42703 SQLCODE=-206: SELECT airports.id AS t0_r0, airports.icao_code AS t0_r1, airports.iata_code AS t0_r2, airports.town AS t0_r3, airports.state AS t0_r4, airports.airport_name AS t0_r5, airports.country_code AS t0_r6, airports.latitude AS t0_r7, airports.longitude AS t0_r8, countries.id AS t1_r0, countries.country_code AS t1_r1, countries.country_name AS t1_r2 FROM airports LEFT OUTER JOIN countries ON countries.id = airports.country_code =============== END OF CUT ============================= In other words it is trying to join looking for an ID column in COUNTRIES. Here''s the trace - =============== START OF CUT ===========================/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in `log'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/ibm_db2_adapter.rb:517:in `execute'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/ibm_db2_adapter.rb:466:in `select_all'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1110:in `select_all_rows'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:975:in `find_with_associations'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:973:in `find_with_associations'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:923:in `find_every'' /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:381:in `find'' app/controllers/airport_controller.rb:19:in `list'' app/controllers/airport_controller.rb:10:in `index'' =============== END OF CUT =============================== --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---