如何按属性限定多态关联的范围
How to scope polymorphic association by attribute
我想根据多态关联的属性编写作用域。
我有模特:
class Item < ApplicationRecord
belongs_to :person, polymorphic: true
end
class Teacher < ApplicationRecord
has_many :items, as: :person
end
class Student < ApplicationRecord
has_many :items, as: :person
end
Teacher 和 Student 都有属性 name,我想将该属性用于范围如:
scope :by_name, ->(name) { joins(:person).where(persons: {name: name}) }
因为我不能只提到范围,所以有什么方法可以很好地确定范围吗?
我不知道这样做的真正干净的方法...这很笨重,但应该可以工作,但不能很好地扩展。希望有人有更好的答案。
scope :by_name, ->(name) { joins("left join teachers on person_type = 'Teacher' and person_id = teachers.id")
.joins("left join students on person_type = 'Student' and person_id = students.id")
.where('teachers.name = ? OR students.name = ?', name, name) }
要处理名称数组,您可以按如下方式修改它...
scope :by_name, ->(*name) do
name = name.flatten
joins("left join teachers on person_type = 'Teacher' and person_id = teachers.id")
.joins("left join students on person_type = 'Student' and person_id = students.id")
.where('teachers.name IN (?) OR students.name IN (?)', name, name)
end
这会让你做到
item.by_name('Smith')
item.by_name('Smith', 'Jones')
item.by_name(['Smith', 'Jones'])
我想根据多态关联的属性编写作用域。
我有模特:
class Item < ApplicationRecord
belongs_to :person, polymorphic: true
end
class Teacher < ApplicationRecord
has_many :items, as: :person
end
class Student < ApplicationRecord
has_many :items, as: :person
end
Teacher 和 Student 都有属性 name,我想将该属性用于范围如:
scope :by_name, ->(name) { joins(:person).where(persons: {name: name}) }
因为我不能只提到范围,所以有什么方法可以很好地确定范围吗?
我不知道这样做的真正干净的方法...这很笨重,但应该可以工作,但不能很好地扩展。希望有人有更好的答案。
scope :by_name, ->(name) { joins("left join teachers on person_type = 'Teacher' and person_id = teachers.id")
.joins("left join students on person_type = 'Student' and person_id = students.id")
.where('teachers.name = ? OR students.name = ?', name, name) }
要处理名称数组,您可以按如下方式修改它...
scope :by_name, ->(*name) do
name = name.flatten
joins("left join teachers on person_type = 'Teacher' and person_id = teachers.id")
.joins("left join students on person_type = 'Student' and person_id = students.id")
.where('teachers.name IN (?) OR students.name IN (?)', name, name)
end
这会让你做到
item.by_name('Smith')
item.by_name('Smith', 'Jones')
item.by_name(['Smith', 'Jones'])