通过rails

时间:2018-02-28 13:09:28

标签: sql ruby-on-rails activerecord arel

我有以下内容(简化和小说化):

  • 小猫有一个名字
  • Kitten与VisitedCountries有多对多的关系(通过KittensVisitedCountry)
  • VisitedCountry有一个country_code,例如'us','gb','fr'等。

我想尝试按照他们去过英国(国家代码'gb'),然后按年龄(desc)来命令我的小猫。例如:

  • 鲍勃去过'fr'和'我们',并且是3yo
  • alice去过'us'和'gb'并且是4yo
  • frances一直无处可去,但是6yo
  • colin去过'gb'并且是2yo

所以在这种情况下,我希望将它们命名为:

  • alice(4) - 因为她是去过英国最古老的人。
  • colin(2) - 因为他是去过英国的最年轻的人。
  • frances(6) - 因为她是最老的,没有去过英国
  • bob(3)

我能得到的最接近的 - 如果它不是多对多的话可能会有效,如下:

Kitten.joins(:visited_countries)
  .select('kittens.*', "(visited_countries.country_code = 'gb') as has_visited_gb")
  .order('has_visited_gb DESC', 'age DESC')

那给了我:

alice (4, gb us}
Colin (2, gb}
alice (4, gb us}
bob (3, us fr}
bob (3, us fr}

显然这不是我们想要的 - 重复,甚至不出现差的法兰西。

我假设需要某种子查询,但我的sql-fu生锈了。我正在使用下面的postgres,如果有任何帮助的话。

编辑:我应该提一下,我已经尝试使用.includes代替.joins - 我相信它会在您尝试时尝试多个SQL语句,因此无法应用选择 - 您将获得这个错误:

Kitten Load (0.7ms)  SELECT  kittens.*, (visited_countries.country_code = 'gb') as has_visited_gb FROM "kittens" ORDER BY has_visited_gb DESC, age DESC LIMIT $1  [["LIMIT", 11]]
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "visited_countries"
LINE 1: SELECT  kittens.*, (visited_countries.country_code = 'gb') a...
                          ^
: SELECT  kittens.*, (visited_countries.country_code = 'gb') as has_visited_gb FROM "kittens" ORDER BY has_visited_gb DESC, age DESC LIMIT $1

编辑2: 我觉得它可以通过忽略VisitedCountry表并在查询中硬编码UK的id来进一步简化它:

Kitten.joins(:kittens_visited_countries).
  select('kittens.*', "(kittens_visited_countries.visited_country_id = 1) as has_visited_gb").
  order('has_visited_gb DESC', 'age DESC')
这给了我: 爱丽丝(4,gb us) 科林(2,gb) 爱丽丝(4,gb us) 鲍勃(3,我们fr) 鲍勃(3,我们fr)

但仍然重复,仍然缺少弗朗西斯。如果我可以让.includes()进行联接而不是多次查询,这可行 - 但我不知道如何鼓励。

0 个答案:

没有答案