合并/合并两个活动记录结果(has_and_belongs_to_many和belongs_to)

时间:2017-04-28 05:50:52

标签: ruby-on-rails postgresql activerecord

我认为这可能是直截了当的,但我似乎无法解决这个问题。

我的Model有以下关联:

has_and_belongs_to_many :locations, join_table: :model_locations
belongs_to :location_from, class_name: "Location", foreign_key: "location_from_id"
belongs_to :location_to, class_name: "Location", foreign_key: "location_to_id"

因此model.locations可以返回0,1或多个记录,model.location_frommodel.location_to始终存在且单个记录。

我正在寻找的是所有这些的综合结果。我知道有一个复杂的SQL查询来做这个,但有一个简单的Active Record语句会很好。我查看了merge()<<,但这些似乎都没有效果。

对于来自has_and_belongs_to_many

的SQL输出的侧面参考
  Location Load (0.6ms)  SELECT "locations".* FROM "locations" INNER JOIN "model_locations" ON "locations"."id" = "model_locations"."location_id" WHERE "model_locations"."model_id" = $1  [["model_id", 17]]

首选答案是通过Active Record,但原始SQL也可以解决问题。

更新

以下答案中的进展 - 仍然会接受赞美我答案的答案。

1 个答案:

答案 0 :(得分:0)

我在那里(某种程度上)。我在这里添加了一个答案,是为了不让问题太长。

这是我的数据:

irb(main):169:0> Location.find_by_sql('SELECT "model_locations".* FROM "model_locations"')
  Location Load (0.5ms)  SELECT "model_locations".* FROM "model_locations"
+----+---------------------+-------------+
| id |            model_id | location_id |
+----+---------------------+-------------+
|    | 17                  | 50          |
|    | 17                  | 51          |
|    | 10                  | 24          |
|    | 19                  | 11          |
|    | 19                  | 5           |
|    | 19                  | 51          |
+----+---------------------+-------------+
6 rows in set

irb(main):174:0> Model.select(:id, :location_from_id, :location_to_id)
  Model Load (0.7ms)  SELECT "models"."id", "models"."location_from_id", "models"."location_to_id" FROM "models"
+----+------------------+----------------+
| id | location_from_id | location_to_id |
+----+------------------+----------------+
| 17 | 1                | 5              |
| 18 | 50               | 24             |
| 10 | 3                | 8              |
| 1  | 50               | 11             |
| 19 | 1                | 5              |
| 20 | 1                | 11             |
| 21 | 11               | 5              |
+----+------------------+----------------+
7 rows in set

例如:

Model 17 has Locations 50, 51 AND 1 ,5 
Location 11 has Models 19, 1 AND 20, 21

所以我可以找到模型位置:

'SELECT "locations".* FROM "locations" LEFT JOIN "model_locations" ON "locations"."id" = "model_locations"."location_id" WHERE "model_locations"."model_id" = 17 OR "locations"."id" IN (1,5)'

这很有效 - 我得到了我的4个位置,但我无法反过来工作:

'SELECT "models".* FROM "models" WHERE "models"."location_from_id" = 11 OR "models"."location_to_id" = 11 INNER JOIN "model_locations" ON "model_locations"."model_id" = "models"."id" WHERE "models_locations"."location_id" = 11'

在INNER JOIN中失败:

PG::SyntaxError: ERROR: syntax error at or near "INNER"

相关问题