【发布时间】:2019-09-30 16:09:55
【问题描述】:
关于如何在 Rails 中为多态关联编写作用域,我发现的很少,更不用说如何编写对多态关联的查询了。
在 Rails 文档中,我查看了 Polymorphic Associations section、Joining Tables section 和 Scopes section。我也做了相当多的谷歌搜索。
以此设置为例:
class Pet < ActiveRecord::Base
belongs_to :animal, polymorphic: true
end
class Dog < ActiveRecord::Base
has_many :pets, as: :animal
end
class Cat < ActiveRecord::Base
has_many :pets, as: :animal
end
class Bird < ActiveRecord::Base
has_many :pets, as: :animal
end
所以Pet 可以是animal_type“狗”、“猫”或“鸟”。
显示所有表结构:这是我的 schema.rb:
create_table "birds", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "cats", force: :cascade do |t|
t.integer "killed_mice"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "dogs", force: :cascade do |t|
t.boolean "sits"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "pets", force: :cascade do |t|
t.string "name"
t.integer "animal_id"
t.string "animal_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
然后我继续做一些记录:
Dog.create(sits: false)
Dog.create(sits: true)
Dog.create(sits: true) #Dog record that will not be tied to a pet
Cat.create(killed_mice: 2)
Cat.create(killed_mice: 15)
Cat.create(killed_mice: 15) #Cat record that will not be tied to a pet
Bird.create
然后我去制作了一些pet 记录:
Pet.create(name: 'dog1', animal_id: 1, animal_type: "Dog")
Pet.create(name: 'dog2', animal_id: 2, animal_type: "Dog")
Pet.create(name: 'cat1', animal_id: 1, animal_type: "Cat")
Pet.create(name: 'cat2', animal_id: 2, animal_type: "Cat")
Pet.create(name: 'bird1', animal_id: 1, animal_type: "Bird")
这就是设置!现在是困难的部分:我想在Pet 模型上创建一些作用域,以挖掘多态关联。
这里有一些我想写的范围:
- 把所有能坐的animal_type == "Dog"的
Pets都给我 - 给我所有的
Pets的 animal_type == "Cat" 至少杀死了 10 只老鼠 - 给我所有的
Pets既不是动物类型“狗”又不能坐的。 (换句话说:给我所有的宠物:所有的宠物:除了不能坐的狗)
所以在我的Pet 模型中,我想把我的范围放在那里:
class Pet < ActiveRecord::Base
belongs_to :animal, polymorphic: true
scope :sitting_dogs, -> {#query goes here}
scope :killer_cats, -> {#query goes here}
scope :remove_dogs_that_cannot_sit, -> {#query goes here} #only removes pet records of dogs that cannot sit. All other pet records are returned
end
我发现编写这些范围非常困难。
我在网上找到的一些东西使您看起来只能使用原始 SQL 编写这些范围。我想知道是否可以对这些范围使用 Hash 语法。
任何提示/帮助将不胜感激!
【问题讨论】:
标签: ruby-on-rails ruby