Ruby on rails 查找其字段为';名称';不包含在任何其他记录中
我有一个型号Ruby on rails 查找其字段为';名称';不包含在任何其他记录中,ruby-on-rails,ruby-on-rails-3,postgresql,activerecord,Ruby On Rails,Ruby On Rails 3,Postgresql,Activerecord,我有一个型号Foo,带有字符串条和字符串名称。某些记录的栏中包含其他记录的名称。这是故意的 我想找到“root Foo”记录,也就是说,它们的名称不会出现在任何其他Foo记录的栏记录中 例如: Foo id: 1 name: 'foo1' bar: 'something something' id: 2 name: 'foo2' bar: 'foo1 something' id: 3 name: 'foo3' bar: 'foo1, foo4' 我的方法root\u foos将返回f
Foo
,带有字符串条和字符串名称。某些记录的栏
中包含其他记录的名称
。这是故意的
我想找到“root Foo”记录,也就是说,它们的名称
不会出现在任何其他Foo
记录的栏
记录中
例如:
Foo
id: 1
name: 'foo1'
bar: 'something something'
id: 2
name: 'foo2'
bar: 'foo1 something'
id: 3
name: 'foo3'
bar: 'foo1, foo4'
我的方法root\u foos
将返回foo2
和foo3
,因为它们的名称不会出现在任何栏中
字符串中
编辑:我不想在这里使用关系或外键-仅此方法。对于任意数量的记录,这将非常缓慢,如果这是一个您需要的查询,我强烈建议您以任意频率重新构造架构,但是:
objs = Model.all.to_a
objs.select { |obj| !objs.any? { |inner_obj| inner_obj[:bar].index(obj[:name]) } }
bar
应该真正实现为数组而不是字符串。然后您可以简化查询和索引:
规范化模式
如链接答案中所述,如果正确实现n:m关系,数据库模式将更干净(查询和索引更简单、更快)。性能取决于许多变量
CREATE TABLE foo
foo_id serial PRIMARY KEY
, foo text
);
CREATE TABLE foo_foo
foo_id1 int REFERENCES foo
, foo_id2 int REFERENCES foo
, PRIMARY KEY (foo_id1, foo_id2) -- provides necessary index automatically
);
那么您的数据将如下所示:
foo
foo_id: 1
foo: 'foo1'
foo_id: 2
foo: 'foo2'
foo_id: 3
foo: 'foo3'
foo_foo
foo_id1: 1
foo_id2: some_id
foo_id1: 1
foo_id2: some_other_id
foo_id1: 2
foo_id2: 1
foo_id1: 2
foo_id2: some_id
foo_id1: 3
foo_id2: 1
foo_id1: 3
foo_id2: 4
以及查询:
SELECT f.*
FROM foo f
WHERE NOT EXISTS (
SELECT 1
FROM foo_foo f2
WHERE f2.foo_id2 = f.foo_id
);
我认为您需要重新构建数据库,并为Foo建立一个自我多对多关系(Foo拥有并属于许多Foo)。这样,您就可以在两个查询中实现您想要的。目前,执行root\u foos
,并填充ActiveRecord位是一件效率极低的事情:将该查询包装在Foo中。通过\u sql(%q{…})
查找模型实例。如果bar
列不是自由格式的文本,那么,是的,该模式需要用棍子敲打。@muistooshort它不是一个标准模式,因为它是一种严重依赖OO模型的东西——也就是说,也许应该使用mongodb来代替…@charlie:“严重依赖OO模型”是指通常的模式吗“数据库中没有逻辑,一切都用Ruby完成“在Rails世界如此流行的胡说八道?顺便说一句,PostgreSQL理解数组列,Rails4本机支持,而postgres_ext
gem允许您将它们与Rails3一起使用。我的经验是,MongoDB所做的工作比它所节省的要多得多。我喜欢Ruby,因为它对OO原则有着非常好的支持,就像我最喜欢的Smalltalk一样——非常遗憾的是,现在流行的做法是破坏对象以将其放入关系数据库。我没有将此列用作数组或任何其他“标准”用法。谢谢你让我知道其他资源,但它们实际上不适合我在这里做的事情。我还重新考虑了我的策略,改用树解析器。如果ruby是面向对象的,我认为在ruby中使用一些逻辑没有什么丢脸的,例如关系数据库不能做的事情。这就是我在这里要做的。不过我很感谢你的帮助。
foo
foo_id: 1
foo: 'foo1'
foo_id: 2
foo: 'foo2'
foo_id: 3
foo: 'foo3'
foo_foo
foo_id1: 1
foo_id2: some_id
foo_id1: 1
foo_id2: some_other_id
foo_id1: 2
foo_id2: 1
foo_id1: 2
foo_id2: some_id
foo_id1: 3
foo_id2: 1
foo_id1: 3
foo_id2: 4
SELECT f.*
FROM foo f
WHERE NOT EXISTS (
SELECT 1
FROM foo_foo f2
WHERE f2.foo_id2 = f.foo_id
);