这是我以前问过的question稍微复杂一点的版本。
背景
所以我需要的是显示文章列表。一篇文章属于媒体渠道。媒体位于特定国家/地区,并以特定语言发布文章。所以数据结构如下:
现在,如果我想通过媒体过滤文章,我可以使用以下类方法(我更喜欢类作用于范围,因为我传递参数并在方法中使用条件语句):
def self.filter_by_media(parameter)
if parameter == "all"
all
else
where(media_id: parameter)
end
end
问题:
如何编写一个类方法,根据其相关模型的属性Media来过滤文章?例如,我想获得一个由某个国家或几个国家的媒体发布的文章列表(当用户没有做出任何选择时,还有一个默认国家/地区)。这是我试过的:
# parameter can be either string 'default' or an array of id’s
def self.filter_by_country(parameter)
if parameter == "default"
joins(:media).where(media: [country_id: 1])
else
joins(:media).where(media: [country_id: parameter])
end
end
但这不起作用,而且我对SQL的熟悉程度不足以弄清楚如何使这项工作。你能帮忙吗?
更新
我正在尝试@ carlosramireziii的建议。我将数组更改为哈希(不知道首先使用的是什么让我使用数组),但我在Rails控制台中遇到以下错误(为避免混淆,在我的数据库中调用media
agency
):
def self.filter_by_country(parameter)
if parameter == "default"
joins(:agency).where(agency: {country_id: 1})
else
joins(:agency).where(agency: {country_id: parameter})
end
end
in Rails console:
> Article.filter_by_country('default')
=> Article Load (1.9ms) SELECT "articles".* FROM "articles" INNER JOIN "agencies" ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."country_id" = 1
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "agency"
LINE 1: ...ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."...
^
: SELECT "articles".* FROM "articles" INNER JOIN "agencies" ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."country_id" = 1
更新2
我在上面更新部分中的错误是我没有在agency
子句中复数where
。部分where(agency: {country_id: 1})
应该已阅读where(agencies: {country_id: 1})
。这里的复数词agencies
指的是正在连接的表的名称。
答案 0 :(得分:2)
你非常接近,你只需要使用嵌套哈希而不是数组。
试试这个
def self.filter_by_country(parameter)
if parameter == "default"
joins(:media).where(media: { country_id: 1 })
else
joins(:media).where(media: { country_id: parameter })
end
end