编辑于 30 日,03:16,以显示改进的迁移和模型
我有一个元素表,每个元素都可以连接到许多其他元素。在 Rails 的迁移和模型中可以做到这一点吗?(以下是用SQL实现的)
元素表:具有整数 id 主键字段以及其他字段。
元素间链接表:
CREATE TABLE inter_element_links
(
element1_id integer NOT NULL,
element2_id integer NOT NULL,
CONSTRAINT inter_element_links_pkey PRIMARY KEY (element1_id, element2_id),
CONSTRAINT foreign_key_on_id1 FOREIGN KEY (element1_id)
REFERENCES elements (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT foreign_key_on_id2 FOREIGN KEY (element2_id)
REFERENCES elements (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
此查询返回通过其 id 链接到特定元素的所有元素,例如 3:
SELECT *
FROM elements
INNER JOIN inter_element_links ON (elements.id = inter_element_links.element1_id
OR elements.id = inter_element_links.element2_id)
WHERE (inter_element_links.element1_id = 3 OR inter_element_links.element2_id = 3)
AND elements.id <> 3
这在 Postgres 中有效,我想翻译成 Rails,但正在努力为 Rails 找到解决方案……我在做什么是愚蠢的,还是只是不那么常见?
到目前为止,我有迁移(它有一个假的复合主键,没有引用 elements.id 的外键):
class CreateInterElementLinks < ActiveRecord::Migration
def self.up
create_table :inter_element_links, :id => false do |t|
t.integer :element1_id, :null => false
t.integer :element2_id, :null => false
end
add_index :inter_element_links, [:element1_id, :element2_id], :unique => true
end
def self.down
remove_index :inter_element_links, [:element1_id, :element2_id]
drop_table :inter_element_links
end
end
并有以下型号:
class Element < ActiveRecord::Base
belongs_to :user
has_many :inter_element_links1, :foreign_key => 'element1_id', :class_name => 'InterElementLink', :dependent => :destroy
has_many :inter_element_links2, :foreign_key => 'element2_id', :class_name => 'InterElementLink', :dependent => :destroy
has_many :elements1, :through => :inter_element_links1
has_many :elements2, :through => :inter_element_links2
def inter_element_links ## Unless there's a more elegant rails solution, I will try to extend ActiveRecord::HasManyThroughAssociation, so things like: an_element.destroy, will destroy the entry in the inter_element_links table, and calls to an_element.elements will work.
inter_element_links1 + inter_element_links2
end
def elements
elements1 + elements2
end
end
class InterElementLink < ActiveRecord::Base
set_primary_keys :element1_id, :element2_id ## I have included the 'composite_primary_keys', '=3.1.0' gem
belongs_to :element
end
任何想法将不胜感激!
在过去的 24 小时内,我发现了一些似乎很接近但还没有完全让我明白的事情:
- 此处讨论了类似的问题,但我无法找到建议的插件,它对迁移方面没有帮助。
- 我已经使用这个插件成功地在 InterElementLink 上获得了 Rails 模拟主键,所以如果有一个 element1_id = 3 和 element2_id = 5,则调用 InterElementLink.find(3,5) 有效,但显然 InterElementLink.find(5,3 ) 不起作用...而 I/ActiveRecord 将需要它。
- 我了解包括 ActiveRecord 在内的 ORM 不支持外键,请参阅有关此的很好的讨论(尽管我知道您可以使用此插件)。 我尝试这样做来制作主键,但失败了。
非常感谢!