这是我之前问的问题的一个更复杂的版本。
背景:
所以我需要的是显示文章列表。一篇文章属于媒体。媒体位于特定国家/地区,并以特定语言发布文章。所以数据结构如下:
- 文章属于媒体;媒体有很多文章
- 媒体属于一个国家;国家有很多媒体
- 媒体属于一种语言;语言有很多媒体
现在,如果我想按媒体过滤文章,我可以使用以下类方法(我更喜欢类方法而不是范围,因为我正在传递一个参数并在方法中使用条件语句):
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
我在上面的更新部分中的错误是我没有在where
子句中复数agency
。where(agency: {country_id: 1})
部分应该读where(agencies: {country_id: 1})
。此处的复数词 agencies
是指正在连接的表的名称。
你非常接近,你只需要使用嵌套哈希而不是数组。
试试这个
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