在红宝石中搜索多面模型

时间:2018-07-10 14:55:32

标签: ruby-on-rails-5 rails-activerecord polymorphic-associations

我有以下模型:

Class Party < ApplicationRecord
  belongs_to :partyable, polymorphic: true
end

Class Person < ApplicationRecord
  has_one :party, as: :partyable, dependent: :destroy
end

Class Organization < ApplicationRecord
  has_one :party, as: :partyable, dependent: : destroy
end

女巫看看这些桌子:

class CreatePeople < ActiveRecord::Migration[5.2]
  def change
    create_table :people do |t|
      t.string :first_name
      t.string :last_name, null: false
      t.string :gender
      t.text :notes
      t.timestamps
    end
  end
end

class CreateOrganizations < ActiveRecord::Migration[5.2]
  def change
    create_table :organizations do |t|
      t.string :name, null: false
      t.string :description
      t.text :notes
      t.timestamps
    end
  end
end

class CreateParties < ActiveRecord::Migration[5.2]
  def change
    create_table :parties do |t|
      t.references :partyable, polymorphic: true
      t.text :notes
      t.timestamps
    end
  end
end

现在,我想搜索“派对”模型并返回名称(如果该派对是组织)或姓(如果该人物是“人”)的给定字符串的派对数组。

目前,当我尝试向人们查询时,我没有成功:

Party.joins("INNER JOIN people ON people.id = parties.partyable_id").select('parties.*,people.last_name').where('last_name like ?', "%Smith%").first

我知道

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: last_name: SELECT  parties.*,people.last_name FROM "parties" INNER JOIN people ON people.id = parties.partyable_id WHERE (last_name like '%Smith%') ORDER BY "parties"."id" ASC LIMIT ?

为什么找不到last_name列?我可以以某种方式改进模型以获得想要的东西吗?有人可以给我建议/提示/解决方案吗?

1 个答案:

答案 0 :(得分:0)

好!典型的输入错误。我键入了 las_name 而不是 last_name 。因此,一种有效的解决方案是:

在models / Party.rb

def self.search(search)
  r1 = joins("INNER JOIN people ON people.id = parties.partyable_id").where('last_name like ?', "%#{search}%")
  r2 = joins("INNER JOIN organizations ON organizations.id = parties.partyable_id).where('name like ?', "%#{search}%")
  r = r1 + r2
  r.uniq{|x| x.id}
end

编辑

我找到了更好的解决方案

scope :search, ->(s) {
    joins("LEFT JOIN people ON people.id = parties.partyable_id").
    joins("LEFT JOIN organizations ON organizations.id = parties.partyable_id").
    where(people.last_name LIKE :s OR organizations.name LIKE :s', s: "%#{s}%")
  }

有人可以提供更好的方法吗?