Rails:对关联模型的属性进行类方法范围界定



这是我之前问的问题的一个更复杂的版本。

背景:

所以我需要的是显示文章列表。一篇文章属于媒体。媒体位于特定国家/地区,并以特定语言发布文章。所以数据结构如下:

  • 文章属于媒体;媒体有很多文章
  • 媒体属于一个国家;国家有很多媒体
  • 媒体属于一种语言;语言有很多媒体

现在,如果我想按媒体过滤文章,我可以使用以下类方法(我更喜欢类方法而不是范围,因为我正在传递一个参数并在方法中使用条件语句):

  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子句中复数agencywhere(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

最新更新