【问题标题】:multi-table, mult-filters postgresql search - rails多表,多过滤器 postgresql 搜索 - rails
【发布时间】:2018-07-11 16:15:15
【问题描述】:

在查看了包括 pg_search 在内的几个选项后,我很难找到可以帮助我了解如何组合多表、多过滤器搜索的资源。我有两个模型,profile 和 subject,它们都通过 unique_id 关联。我想做的是让用户从众多过滤器中选择,跨越许多模型,并返回结果。例如,我希望用户能够从配置文件模型中搜索 name 属性和从主题模型中搜索 grade 属性并返回一个列表那些搜索参数。创建一个搜索过滤器没有问题,但是当我为不同类别添加更多过滤器时,其他搜索过滤器似乎没有相互通信。下面是我的一些代码。很高兴添加更多代码,只是真的不知道在哪里使用它。非常感谢您提供的任何帮助或指导。

个人资料数据库

class CreateProfiles < ActiveRecord::Migration
  def change
    create_table :profiles do |t|
      t.integer :unique_id
      t.string :name
      t.integer :age
      t.string :sex
      t.references :user, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

主题数据库

class CreateSubjects < ActiveRecord::Migration
  def change
    create_table :subjects do |t|
      t.integer :unique_id
      t.string :subject
      t.integer :grade
      t.references :user, index: true, foreign_key: true

      t.timestamps null: false
    end
  end
end

个人资料模型

class Profile < ActiveRecord::Base

include PgSearch

  belongs_to :user

    def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
    attributes = row.to_hash
    Profile.create! attributes
   end 
  end


end

主题模型

class Subject < ActiveRecord::Base

      include PgSearch

      belongs_to :user

      def self.import(file)
        CSV.foreach(file.path, headers: true) do |row|
        attributes = row.to_hash
        Subject.create! attributes
       end 
      end

    end

【问题讨论】:

    标签: ruby-on-rails ruby postgresql pg-search


    【解决方案1】:

    看看Rails join table queriesRails method chaining 开始吧。

    让我们看一些你可能会做什么的例子。假设您要查找个人资料名称为“John”且主题为 100 的用户。您可以执行以下操作:

    @users = User.where(profiles: { name: "John" }, subjects: { grade: 100 }).joins(:profiles, :subjects)
    

    请注意,仅当您根据特定值进行过滤时,才可以使用哈希方法。现在假设您要查找个人资料名称为“John”(例如“John”、“John Smith”或“John Doe”)且成绩大于 85 的用户,您可以执行以下操作:

    @users = User.where("profiles.name ILIKE ? AND subjects.grade > ?", "John%", 85).joins(:profiles, :subjects)
    

    ILIKE 查询适用于 Postgres,而不是我记得的 MySQL。请注意,在这两个语句中,您都必须在查询中提及连接表名称,并且您还必须调用 joins 方法。

    既然您知道如何连接表,我们现在可以看看如何使用参数和范围来过滤它。

    class User
      scope :by_profile_name, -> (input) do
        where("profiles.name = ?", input[:profile_name]).joins(:profiles) if input[:profile_name]
      end
    
      scope :by_subject_grade, -> (input) do
        where("subjects.grade = ?", input[:subject_grade].to_i).joins(:subjects) if input[:subject_grade]
      end
    end
    

    然后在您的控制器中,您将拥有:

    @users = User.by_subject_grade(params).by_profile_name(params)
    

    这只是一个粗略的开始,请查看上面的链接了解更多详细信息。

    【讨论】:

    • 非常感谢,格雷格。这对我开始很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多