[英]rails polymorphic association (legacy database)
I am using a legacy database, so i do not have any control over the datamodel. 我正在使用遗留数据库,因此我无法控制数据模型。 They use a lot of polymorphic link/join-tables, like this 他们使用了很多多态链接/连接表,就像这样
create table person(per_ident, name, ...)
create table person_links(per_ident, obj_name, obj_r_ident)
create table report(rep_ident, name, ...)
where obj_name
is the table-name, and obj_r_ident
is the identifier. 其中obj_name
是表名, obj_r_ident
是标识符。 So linked reports would be inserted as follows: 所以链接的报告将插入如下:
insert into person(1, ...)
insert into report(1, ...)
insert into report(2, ...)
insert into person_links(1, 'REPORT', 1)
insert into person_links(1, 'REPORT', 2)
And then person 1 would have 2 linked reports, 1 and 2. 然后,人1将有2个链接报告,1和2。
I can understand possible benefits having a datamodel like this, but i mostly see one big shortcoming: using constraints is not possible to ensure data integrity. 我可以理解像这样的数据模型可能带来的好处,但我主要看到一个很大的缺点:使用约束不可能确保数据完整性。 But alas, i cannot change this anymore. 但是,唉,我不能再改变它了。
But to use this in Rails, i was looking at polymorphic associations but did not find a nice way to solve this (since i cannot change the columns-names, and did not readily find a way to do that). 但是要在Rails中使用它,我正在寻找多态关联,但没有找到一个很好的方法来解决这个问题(因为我不能改变列名,并且没有找到办法做到这一点)。
I did come up with a solution though. 我确实提出了一个解决方案。 Please provide suggestions. 请提供建议。
class Person < ActiveRecord::Base
set_primary_key "per_ident"
set_table_name "person"
has_and_belongs_to_many :reports,
:join_table => "person_links",
:foreign_key => "per_ident",
:association_foreign_key => "obj_r_ident",
:conditions => "OBJ_NAME='REPORT'"
end
class Report < ActiveRecord::Base
set_primary_key "rep_ident"
set_table_name "report"
has_and_belongs_to_many :persons,
:join_table => "person_links",
:foreign_key => "obj_r_ident",
:association_foreign_key => "per_ident",
:conditions => "OBJ_NAME='REPORT'"
end
This works, but i wonder if there would be a better solution, using polymorphic associations. 这有效,但我想知道是否会有更好的解决方案,使用多态关联。
At least as of Rails 4.2.1, you can pass foreign_type
to a belongs_to declaration to specify the name of the column to be used for the 'type' of the polymorphic association 至少从Rails 4.2.1开始,您可以将foreign_type
传递给belongs_to声明,以指定用于多态关联的“类型”的列的名称
http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/ClassMethods/belongs_to http://apidock.com/rails/v4.2.1/ActiveRecord/Associations/ClassMethods/belongs_to
You can override the column names, sure, but a quick scan of the Rails API didn't show me anywhere to override the polymorphic 'type' column. 当然,您可以覆盖列名称,但是快速扫描Rails API并没有向我显示覆盖多态“类型”列的任何地方。 So, you wouldn't be able to set that to 'obj_name'. 因此,您无法将其设置为“obj_name”。
It's ugly, but I think you'll need a HABTM for each type of object in your table. 这很难看,但我认为你需要为表中的每种类型的对象使用HABTM。
You might be able to do something like this: 你可以做这样的事情:
{:report => 'REPORT'}.each do |sym, text|
has_and_belongs_to_many sym,
:join_table => "person_links",
:foreign_key => "obj_r_ident",
:association_foreign_key => "per_ident",
:conditions => "OBJ_NAME='#{text}'"
end
At least that way all the common stuff stays DRY and you can easily add more relationships. 至少在这种情况下,所有常见的东西都会保持DRY ,您可以轻松添加更多关系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.