首页 > 解决方案 > Rails API - 如何构建查询以过滤字符串数组?

问题描述

我需要制作一个简单的 API 并添加以下功能:

GET /tools?tag=node (EXAMPLE)

工具模型具有以下列:
*标题(字符串)
*描述(文本)
*链接(字符串)
*标签(字符串数组)

我需要能够从 localhost 中搜索所有带有标签的工具。我尝试使用Rack Reducer,但此方法仅适用于字符串或文本类型。

我知道这应该很简单,但我是 Rails 的新手。

谢谢你的帮助。

架构.rb:

ActiveRecord::Schema.define(version: 2019_11_29_170156) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "tools", force: :cascade do |t|
    t.string "title"
    t.string "link"
    t.text "description"
    t.text "tags", default: [], array: true
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end

tools_controller.rb

class ToolsController < ApplicationController

  ToolReducer = Rack::Reducer.new(
    Tool.all,
    # ->(tags:) { select { |item| item[:tags].match(/#{tags}/i) } }
    ->(tags:) { where("tags @> ?", "%#{tags}%") }
  )

  def index
    # @tools = Tool.where(query_params)
    @tools = ToolReducer.apply(params)
    # @tools = Tool.all
    render json: @tools
  end

  def new
    @tool = Tool.new
  end

  def show
    @tool = Tool.find(params[:id])
    render json: @tool
  end

  def create
    @tool = Tool.new(tool_params)
    if @tool.save
      render json: @tool
      redirect_to @tool
    end
  end

  def destroy
    @tool = Tool.find(params[:id])
    @tool.destroy
  end

  private

    def tool_params
      params.require(:tool).permit(:title, :link, :description, :tags)
    end
end

标签: ruby-on-railspostgresqlapiruby-on-rails-5

解决方案


pg_searchgem 非常适合在 Postgres 数据库中进行搜索。

但是,就您而言,我认为您的应用程序设计不佳。

与其将标签存储在“工具”模型的字段中,不如创建一个名为“标签”的新模型,并在标签模型和工具模型之间创建 has_and_belongs_to_many 关系。

查找和删除标签会容易得多。

(还有任何与机架相关的东西都会深入到你的应用程序中,它是中间件。我不知道 Rack::reducer 但我相信你不需要它)


推荐阅读