我想获取在 Rails 4 中以 ActiveRecord 和 Postgres 作为数据库的一对多关系的特定日期创建的所有父记录,没有记录。
迁移:
class CreateParents < ActiveRecord::Migration
def change
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
create_table :parents, id: :uuid, default: 'gen_random_uuid()' do |t|
t.string :name
t.timestamps null: false
end
end
class CreateChilds < ActiveRecord::Migration
def change
create_table :childs, id: false do |t|
t.uuid :parent_id, null: false
t.date :created_at, null: false
t.string :name
end
add_foreign_key :childs, :parents
add_index :childs, [:parent_id, :created_at], :unique => true
end
end
模型:
class Parent < ActiveRecord::Base
has_many :childs
end
class Child < ActiveRecord::Base
belongs_to :parent
end
现在我想让所有在特定日期没有 child 的 parent 有一个范围:
class Parent < ActiveRecord::Base
has_many :childs
def self.with_no_childs_created_at(date)
...
end
end
有人能帮帮我吗?我真的要疯了。我用 .includes
、.references
、.where
、.not
、 尝试了很多东西。加入
等,但我不明白。
更新 1
一个建议的解决方案如下所示:
def self.with_no_stats_created_at(date)
joins(:childs).where.not(childs: {created_at: date})
end
但这只有在父对象过去已经创建了子对象的情况下才有效。 SQL 应该证明问题:
SELECT "parents".*
FROM "parents"
INNER JOIN "childs" ON "childs"."parent_id" = "parents"."id"
WHERE ("childs"."created_at" != $1) [["created_at", "2016-04-19"]]
更新 2
这解决了问题(@Ilya 建议):
def self.with_no_childs_created_at(date)
preload(:childs).select {|p| p.childs.all? {|c| c.created_at != date }}
end
最佳答案
您可以预加载 child 以避免 N+1
查询并像处理数组一样处理它:
def self.with_no_childs_created_at(date)
preload(:childs).select {|p| p.childs.all? {|c| c.created_at != date }}
end
关于ruby-on-rails - ActiveRecord:获取在特定日期没有创建 child 的 parent 的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36728399/