David Blundell
2005-Aug-13 16:11 UTC
Single Table Inheritance seems to ignore :foreign_key
I am using rails 0.13.1 with postgresql. I have two base classes: Zone and Record. Each of these has another class (MasterZone and NameServer) using single table inheritance. A column in the records table is called zone_id but when I create a new NameServer it always tries to save to the non-existent column master_zone_id. Adding :foreign_key => "zone_id" does not make any difference. I am unsure if this is a bug or if I am missing something. The simplified code looks like this: CREATE TABLE records ( "id" serial PRIMARY KEY NOT NULL, "zone_id" integer REFERENCES zones (id) NOT NULL, "type" varchar NOT NULL, "ttl" integer NOT NULL ); class Zone < ActiveRecord::Base end class MasterZone < Zone has_many :records, :foreign_key => "zone_id" end class Record < ActiveRecord::Base belongs_to :master_zone, :foreign_key => "zone_id" end class NameServer < Record end If I create a new MasterZone and NameServer and try to save it with the following snippet: @zone = MasterZone.new(@params[:zone]) @name_server_1 = NameServer.new(@params[:name_server_1]) @name_server_2 = NameServer.new(@params[:name_server_2]) @name_server_2.ttl = @name_server_1.ttl @account.master_zones << @zone I get the error saving the NameServers: ERROR: null value in column "zone_id" violates not-null constraint If I rename the column in the database to master_zone_id it all works but I would like to keep the column as zone_id as lots of other scripts rely on it. Is there any other way to make activerecord save using a foreign key of zone_id? Thanks in advance for any help, David
Zachery Hostens
2005-Aug-14 01:51 UTC
Re: Single Table Inheritance seems to ignore :foreign_key
david, my guess is your trying to save a record/zone but NOT associating a zone/masterzone with it, and thus the value is null. but in your schema you specifically state its NOT NULL. the example also isnt a huge help as we have a schema for 1 table, class definitions for 2 different tables, and example code for 2 other tables. On 8/13/05, David Blundell <david.blundell-7ie3GnOy+6yuWcBOZErdyg@public.gmane.org> wrote:> I am using rails 0.13.1 with postgresql. I have two base classes: Zone > and Record. Each of these has another class (MasterZone and NameServer) > using single table inheritance. A column in the records table is called > zone_id but when I create a new NameServer it always tries to save to > the non-existent column master_zone_id. > > Adding :foreign_key => "zone_id" does not make any difference. I am > unsure if this is a bug or if I am missing something. > > The simplified code looks like this: > > CREATE TABLE records ( > "id" serial PRIMARY KEY NOT NULL, > "zone_id" integer REFERENCES zones (id) NOT NULL, > "type" varchar NOT NULL, > "ttl" integer NOT NULL > ); > > class Zone < ActiveRecord::Base > end > > class MasterZone < Zone > has_many :records, :foreign_key => "zone_id" > end > > class Record < ActiveRecord::Base > belongs_to :master_zone, :foreign_key => "zone_id" > end > > class NameServer < Record > end > > If I create a new MasterZone and NameServer and try to save it with the > following snippet: > > @zone = MasterZone.new(@params[:zone]) > @name_server_1 = NameServer.new(@params[:name_server_1]) > @name_server_2 = NameServer.new(@params[:name_server_2]) > @name_server_2.ttl = @name_server_1.ttl > @account.master_zones << @zone > > I get the error saving the NameServers: > > ERROR: null value in column "zone_id" violates not-null constraint > > If I rename the column in the database to master_zone_id it all works > but I would like to keep the column as zone_id as lots of other scripts > rely on it. Is there any other way to make activerecord save using a > foreign key of zone_id? > > Thanks in advance for any help, > > David > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Zachery Hostens <zacheryph-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
David Blundell
2005-Aug-14 08:22 UTC
Re: Single Table Inheritance seems to ignore :foreign_key
On Sat, 2005-08-13 at 21:51 -0400, Zachery Hostens wrote:> david, > > my guess is your trying to save a record/zone but NOT associating a > zone/masterzone with it, and thus the value is null. but in your > schema you specifically state its NOT NULL.Hi Zachery, Thanks for your help. All four class definitions are in the example code (I removed all domain logic from them to give the least amount of code that causes the problem) - I missed two lines when I cut and pasted. The last three lines should be: @zone.name_servers << @name_server_1 @zone.name_servers << @name_server_2 @account.master_zones << @zone When this is processed, the logs indicate that the zone is saved correctly and then the nameserver save fails. The problem is that the nameserver tries to save its association to the zone in a column called master_zone_id and leaves the column zone_id null - triggering the error. If I rename the database column to "master_zone_id" everything works fine. I cannot find a way to make the nameserver use the column "zone_id" as belongs_to :master_zone, :foreign_key => "zone_id" has no effect. :foreign_key seems to work fine on all other objects I create, it just has no effect when used with single table inheritance. This whole system works fine when used with normal objects and separate a_record, ns_record etc. tables and a postgresql view pulls them all together - I am refactoring to use STI as it is a lot faster than using a view when I need to sort and reorder. The view column is called zone_id and as other scripts use this I would love to find a way to keep the same name. Is there any way to make nameserver save its association to masterzone using a foreign key of zone_id? Thanks, David
Zachery Hostens
2005-Aug-14 16:59 UTC
Re: Single Table Inheritance seems to ignore :foreign_key
david. from you example AR knows of NO relationships with the name_server object. you have no relations setup, so for any zone_id/master_zone_id field you would have to set it yourself. On 8/14/05, David Blundell <david.blundell-7ie3GnOy+6yuWcBOZErdyg@public.gmane.org> wrote:> On Sat, 2005-08-13 at 21:51 -0400, Zachery Hostens wrote: > > david, > > > > my guess is your trying to save a record/zone but NOT associating a > > zone/masterzone with it, and thus the value is null. but in your > > schema you specifically state its NOT NULL. > Hi Zachery, > > Thanks for your help. All four class definitions are in the example > code (I removed all domain logic from them to give the least amount of > code that causes the problem) - I missed two lines when I cut and > pasted. The last three lines should be: > > @zone.name_servers << @name_server_1 > @zone.name_servers << @name_server_2 > @account.master_zones << @zone > When this is processed, the logs indicate that the zone is saved > correctly and then the nameserver save fails. > > The problem is that the nameserver tries to save its association to the > zone in a column called master_zone_id and leaves the column zone_id > null - triggering the error. If I rename the database column to > "master_zone_id" everything works fine. I cannot find a way to make the > nameserver use the column "zone_id" as > belongs_to :master_zone, :foreign_key => "zone_id" > has no effect. > > :foreign_key seems to work fine on all other objects I create, it just > has no effect when used with single table inheritance. This whole > system works fine when used with normal objects and separate a_record, > ns_record etc. tables and a postgresql view pulls them all together - I > am refactoring to use STI as it is a lot faster than using a view when I > need to sort and reorder. The view column is called zone_id and as > other scripts use this I would love to find a way to keep the same name. > > Is there any way to make nameserver save its association to masterzone > using a foreign key of zone_id? > > Thanks, > > David > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Zachery Hostens <zacheryph-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>