【问题标题】:Ruby on Rails - Return all records where child record matches element in an arrayRuby on Rails - 返回子记录与数组中元素匹配的所有记录
【发布时间】:2016-08-31 17:30:29
【问题描述】:

从标题上看,这听起来有点复杂,但实际上不应该如此。我将 Rails 用于 API,并且有一个接受一系列项目的端点。我想返回属于它的记录与数组中至少一个元素匹配的所有记录。

例如,假设我正在创建一个博客,并且我有帖子和标签。

我可能会要求类似:

GET http://localhost:3000/api/v1/posts_by_tag?tags=news,weather,life

然后在 routes.rb

get '/posts_by_tag' => 'posts#index_by_tag'

posts_controller.rb

def index_by_tag
  tags =  params[:tags].split(',')
  @posts = Post.where( any element in Post.tags matches any element in tags )
  render json: @posts.to_json, status: :ok
end

在上面的假设示例中,我想返回所有带有“新闻”、“天气”或“生活”标签的帖子。

我来自 node,最近没有花太多时间在 Rails 上。但这感觉就像有一种非常明确的 Rails/ActiveRecord 方式来执行此操作。

【问题讨论】:

  • 这是一个什么样的数组?你用的是什么数据库?
  • 我使用的是 Postgres,数组就是 Ruby 的 String.split() 方法生成的任何类型的数组。
  • 但是 post.tags 是什么类型的数组呢?它是 Postgres 数组吗?
  • 这是一个关联模型。发布 has_many 标签

标签: ruby-on-rails activerecord ruby-on-rails-5 rails-api


【解决方案1】:

我假设您有一个模型 Tag,它通过一个名为 PostTagging 的模型连接到 Post

class PostTagging < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

class Post < ActiveRecord::Base
  has_many :post_taggings
  has_many :tags, through: :post_taggings
end

因此,要获取带有该标签的所有帖子,您只需加入 TagPost 并搜索 Tag 模型:

Post.joins(:tags).where(tags: { name: tags })

您可以这样做joins(:tags),因为您在Post 中指定了一个关系,而在where 中的tags 是一个标签名称数组。轻轻松松!

【讨论】:

  • 根据OP,没有中间模型,直接has_many-association。此外,如果标签数组中有多个匹配的标签,您的示例将多次返回相同的帖子。 .distinct 应该处理好这个。
  • 我找不到他没有中间模型的 OP 状态,但如果他没有,那么 pankaj 答案就可以了 :)
  • 不,pankaj 的回答仅适用于检查帖子的单个 tag-attribute。
  • 您好,抱歉,我应该更清楚一点。正如@shlajin 正确假设的那样,有一个关联的模型。它通过 post_taggings 模型进行多对多关联。这个答案完美无缺。谢谢!
【解决方案2】:
Post.where(tags: tags) => 
  SELECT `posts`.* 
  FROM `posts` 
  WHERE `posts`.`tags` 
  IN ('News', 'Weather', 'Life')

【讨论】:

    猜你喜欢
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-17
    • 2016-05-24
    • 1970-01-01
    相关资源
    最近更新 更多