ruby on rails - ActiveRecord: Scope to get parents with no children created at a specific date -
i want parent records no records created @ specific date on one-to-many relation in rails 4 activerecord , postgres database.
migrations:
class createparents < activerecord::migration def change enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') create_table :parents, id: :uuid, default: 'gen_random_uuid()' |t| t.string :name t.timestamps null: false end end class createchilds < activerecord::migration def change create_table :childs, id: false |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
models:
class parent < activerecord::base has_many :childs end class child < activerecord::base belongs_to :parent end
now want parents no child @ specific date scope:
class parent < activerecord::base has_many :childs def self.with_no_childs_created_at(date) ... end end
can me? i'm going crazy this. tried lot things .includes
, .references
, .where
, .not
, .joins
etc. don't it.
update 1
one suggested solution looked likes this:
def self.with_no_stats_created_at(date) joins(:childs).where.not(childs: {created_at: date}) end
but works if parent has child created in past. sql should demonstrate problem:
select "parents".* "parents" inner join "childs" on "childs"."parent_id" = "parents"."id" ("childs"."created_at" != $1) [["created_at", "2016-04-19"]]
update 2
this solved problem (suggested @ilya):
def self.with_no_childs_created_at(date) preload(:childs).select {|p| p.childs.all? {|c| c.created_at != date }} end
you can preload childs avoid n+1
queries , process array:
def self.with_no_childs_created_at(date) preload(:childs).select {|p| p.childs.all? {|c| c.created_at != date }} end
Comments
Post a Comment