find_or_create没有传递第二个条件来创建

时间:2013-05-17 18:27:59

标签: sql ruby-on-rails ruby-on-rails-3 activerecord

这里有两个实体 - 设施和代理商。每个设施belongs_to :agency

我正在为数据库编写种子脚本,该脚本读取CSV文件并解析数据。

这应该添加设施及其名称和所属的代理机构:

Facility.joins(:agency)
.where(name: row[:name], agencies: { code: agency_code })
.first_or_create

我验证了.where(name: row[:name], agencies: { code: agency_code })之前的部分完全符合我的要求:

SELECT `facilities`.* FROM `facilities`
INNER JOIN `agencies` ON `agencies`.`id` = `facilities`.`agency_id`
WHERE `facilities`.`name` = 'Awesomesauce factory'
AND `agencies`.`code` = 'ROFL'

正如您所看到的,连接是必要的,因为我没有对代理商的ID进行硬编码,在这种情况下我需要知道哪一个是ROFL

已经插入了代理商,因此已经有一个代码为ROFL的代理商。我的问题是在创建步骤期间,WHERE子句中的第二个条件不会传递:

INSERT INTO `facilities` (`agency_id`, `created_at`, `name`, `updated_at`)
VALUES (NULL, '2013-05-17 18:16:53', 'Awesomesauce Factory','2013-05-17 18:16:53')

看到NULL作为第一个值?这就是我想解决的问题。现在我实际上传递了一个代码块,通过对具有该代理商代码的代理商执行查询来手动设置它,但看起来这应该可以在没有使用子查询的黑客攻击的情况下工作。我想要产生的是:

INSERT INTO `facilities` (`agency_id`, `created_at`, `name`, `updated_at`)
VALUES (
(SELECT `agency_id` FROM `agencies` WHERE `code` = 'ROFL'),
'2013-05-17 18:16:53', 'Awesomesauce Factory','2013-05-17 18:16:53')

1 个答案:

答案 0 :(得分:0)

您尝试做的事情是不可能的,因为没有一个独特的agency_id可以满足您的条件。 (SELECT 'agency_id' FROM 'agencies' WHERE 'code' = 'ROFL')返回一组记录,其长度可能是也可能不是1.

总之,这不是框架的限制。它无法确定您编写的代码中的agency_id应该是什么。