【发布时间】:2015-05-06 10:45:43
【问题描述】:
我有一个组织和行动代码模型。注册高级帐户时,组织可以输入折扣的操作代码。因此,一个组织没有使用或使用 1 个操作代码,而一个操作代码可以被许多组织使用。
当前关联:
Organizations migration file: t.references :actioncode, index: true, foreign_key: true
Organization model: belongs_to :actioncode
Actioncode model: has_many :organizations
此设置的初始问题:actioncode_id 不应该是强制性的 在播种时,我曾经得到错误代码 ActiveRecord::AssociationTypeMismatch: Actioncode(#23575660) expected, got Fixnum(#5494220)。原因似乎是 actioncode_id 已成为组织模型中的必填列。不应该是这种情况; actioncode 也应该能够是 nil,因为组织在支付高级帐户时也可能不使用/拥有任何 actioncode。
当前情况:升级到 PostgreSQL 后: 作为回应,我已将我的数据库升级到 PostgreSQL。不过,现在在迁移时,我收到了错误消息(请参阅帖子底部的完整消息):
PG::UndefinedTable: 错误:关系“actioncodes”不存在
错误消息: 知道是什么导致了这个错误吗?删除“当前关联”下的三行,我对迁移和播种没有任何问题。事实上,保留所有三行但从第一行中删除 index: true, foreign_key: true 并且它也可以正确迁移。当我在迁移时保留index: true 时,它会给出错误:SyntaxError: xxx_create_organizations.rb:17: syntax error, unexpected tSYMBEG, expecting => t.boolean :activated。当我保留foreign_key: true 时,它会产生原始错误消息PG::UndefinedTable。
如果我将第一行更改为不正确的代码:t.references :actioncode_id, index: true, foreign_key: true,则会出现以下错误:
PG::UndefinedTable: ERROR: relation "actioncode_ids" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_604f95d1a1"
FOREIGN KEY ("actioncode_id_id")
REFERENCES "actioncode_ids" ("id")
因此,鉴于最后一行的 _ids,Rails 似乎确实在表名方面存在问题。将self.table_name = 'actioncodes' 添加到动作代码模型文件中没有任何区别。怎么办?
替代联想:
我想知道我是否需要一个替代协会来满足我的需要。我调查了其他几个协会,但不确定该怎么做。最佳情况下,我在组织模型中只有一个列,其中包含使用的操作代码,如果没有使用操作代码,则为 nil。例如,我需要一个模型关联来打印所有使用特定操作代码的组织。
替代关联 1: 这种关联的问题在于 actioncode 在组织模型中仍然是强制变量,因此不能为 nil。
Organization migration: t.references :actioncode, index: true, foreign_key: true
Organization model: has_one :actioncode
Actioncode model: has_many :organizations
替代关联 2: 该关联会将 organization_id 保存在 actioncodes 表中(我猜是一个数组),而从我的角度来看,将 actioncode_id 包含在组织表中会更有意义.此外,下面的代码仍然需要每个组织的操作代码。
Organization model: has_one :actioncode
Actioncodes migration file: t.belongs_to :organization, index: true
替代关联 3: 我也考虑过创建一个额外的关联模型,但这让我怀疑当我遵循这个策略时我是否没有想太多,因为这会增加一个额外的表/模型。另外,我不确定下面的组织模型是否仍然不需要折扣值,从而不能真正解决最初的问题。但如果这是要走的路,我在想:
Organization model: has_one :discount
has_one :actioncode, through: :discount
Discount model: belongs_to :organization
has_one :actioncode
Actioncode model: belongs_to :discount
Discount migration: t.belongs_to :organization, index: true
doesn;t need any other columns
Actioncode migration: t.belongs_to :discount, index: true
替代关联 4: 最后,has_and_belongs_to_many 关联对我来说没有意义,因为我如何理解它是针对多:多关系的,而组织:操作代码是多:1/ 0 关系。
我应该使用什么设置并且没有将操作码作为组织的强制变量?
附加信息:在rake db:drop和rake db:create之后运行rake db:migrate的SQL):
== 20150410153815 CreateUsers: migrating ===============================
-- create_table(:users)
-> 0.0582s
== 20150410153815 CreateUsers: migrated (0.0628s) ======================
== 20150410200022 AddIndexToUsersEmailAndUsername: migrating ===========
-- add_index(:users, :email, {:unique=>true})
-> 0.0109s
-- add_index(:users, :username, {:unique=>true})
-> 0.0100s
== 20150410200022 AddIndexToUsersEmailAndUsername: migrated (0.0219s) ==
== 20150416113853 CreateOrganizations: migrating ==============================
-- create_table(:organizations)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "actioncodes" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_4ecaa2493e"
FOREIGN KEY ("actioncode_id")
REFERENCES "actioncodes" ("id")
/usr/local/rvm/gems/ruby-2.1.5/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec'
<<SNIP>>
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "actioncodes" does not exist
: ALTER TABLE "organizations" ADD CONSTRAINT "fk_rails_4ecaa2493e"
FOREIGN KEY ("actioncode_id")
REFERENCES "actioncodes" ("id")
/usr/local/rvm/gems/ruby-2.1.5/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:155:in `async_exec'
<<SNIP>>
其他信息:运行当前关联的迁移中的 SQL(运行rake db:drop,然后运行rake db:setup):
-- enable_extension("plpgsql")
-> 0.0664s
-- create_table("actioncodes", {:force=>:cascade})
-> 0.0412s
-- add_index("actioncodes", ["actioncode"], {:name=>"index_actioncodes_on_actioncode", :unique=>true, :using=>:btree})
-> 0.0217s
-- create_table("organizations", {:force=>:cascade})
-> 0.0237s
-- add_index("organizations", ["summ"], {:name=>"index_organizations_on_summ", :unique=>true, :using=>:btree})
-> 0.0106s
-- add_index("organizations", ["name"], {:name=>"index_organizations_on_name", :unique=>true, :using=>:btree})
-> 0.0197s
<<SNIP, OTHER TABLES >>
-- initialize_schema_migrations_table()
-> 0.0352s
-- enable_extension("plpgsql")
-> 0.0405s
-- create_table("actioncodes", {:force=>:cascade})
-> 0.0176s
-- add_index("actioncodes", ["actioncode"], {:name=>"index_actioncodes_on_actioncode", :unique=>true, :using=>:btree})
-> 0.0085s
-- create_table("organizations", {:force=>:cascade})
-> 0.0148s
-- add_index("organizations", ["summ"], {:name=>"index_organizations_on_summ", :unique=>true, :using=>:btree})
-> 0.0113s
-- add_index("organizations", ["name"], {:name=>"index_organizations_on_name", :unique=>true, :using=>:btree})
-> 0.0195s
<<SNIP, OTHER TABLES >>
-- initialize_schema_migrations_table()
-> 0.0342s
rake aborted!
ActiveRecord::AssociationTypeMismatch: Actioncode(#39911240) expected, got Fixnum(#20092360)
/usr/local/rvm/gems/ruby-2.1.5/gems/activerecord-4.2.1/lib/active_record/associations/association.rb:216:in `raise_on_type_mismatch!'
<<SNIP >>
【问题讨论】:
标签: ruby-on-rails ruby postgresql ruby-on-rails-4 associations