Rails add_foreign_key limited to a single reference field

时间:2017-09-20 13:05:08

标签: ruby-on-rails postgresql activerecord

I am working with a database that uses a lot of constraints defined within the schema. This is necessary, to ensure that other services and clients that use the database do not break the data model (please don't reply that this level of DB definition is inappropriate for a Rails application). Unfortunately this seems to take Rails beyond its ability to define, dump and subsequently recreate schemas, unless somebody knows something that I have missed.

The specific issue that I have encountered is with add_foreign_key statements in schema.rb, and I am looking to see if anybody knows a workaround that will save me embedding SQL directly into the schema.rb definition.

The Postgres DDL that I need to represent is:

ALTER TABLE ONLY trackers
  ADD CONSTRAINT valid_protocol_sub_process 
  FOREIGN KEY (protocol_id, sub_process_id) 
  REFERENCES sub_processes(protocol_id, id) MATCH FULL;

Unfortunately, when I rake db:schema:dump the existing database to schema.rb this results in the following:

add_foreign_key "trackers", "sub_processes", 
  column: "protocol_id", 
  primary_key: "protocol_id", 
  name: "valid_protocol_sub_process"

This results in an invalid specification, when recreating the database, that only includes a single field and (fortunately) fails to run, since the resulting schema constraints would be incorrect.

I have attempted to change the primary_key and column option strings to include both fields to match the required SQL, but ActiveRecord puts quotes around the whole lot, making the SQL statement invalid. I also attempted to use an array of columns too, but it appears to just #to_s the array.

Is this just beyond the ability of add_foreign_key, or is there a way to use multiple fields in a foreign key specification?

1 个答案:

答案 0 :(得分:0)

如果您使用特定于数据库的DDL,则似乎没有检查schema.rb是否可以有效地表示完整数据库。虽然我理解schema.rb可能无法表示所有可能性,但遗憾的是没有产生错误来指示rake生成的schema.rb无效。

为了获得由数据库自己的架构转储工具执行的数据库的完整SQL转储,我添加了:

config.active_record.schema_format = :sql

到application.rb。这可以确保将来我获得一个有效的,可用的数据库模式来重建环境。