在 ruby 中搜索多态模型
Searching Polymorhic models in ruby
我有这些型号:
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
现在,我想搜索派对模型和 return 名称中包含给定字符串的派对数组(如果派对是组织)或 last_name(如果派对是一个人)
目前,当我尝试查询我没有成功的人时:
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 列?我能以某种方式改进模型以获得我想要的吗?有人可以给我一个 advice/hint/solution 吗?
好的!典型的打字错误。我输入了 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}%")
}
有人可以提供更好的方法吗?
我有这些型号:
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
现在,我想搜索派对模型和 return 名称中包含给定字符串的派对数组(如果派对是组织)或 last_name(如果派对是一个人)
目前,当我尝试查询我没有成功的人时:
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 列?我能以某种方式改进模型以获得我想要的吗?有人可以给我一个 advice/hint/solution 吗?
好的!典型的打字错误。我输入了 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}%")
}
有人可以提供更好的方法吗?