Open noctivityinc opened 10 years ago
That's... already supported? I thought? post.comments.with_deleted
?
Sorry for not being clear. I mean in the belongs_to or has_many declarations.
belongs_to :something, with_deleted: true
Would be really helpful when you have like:
delegate :stuff, to: :something
an something is soft_deleted
Rails 4 (not sure about 3) allows custom scopes for associations:
belongs_to :whatever, -> { with_deleted }
Therefore support should be fine there.
using with_deleted in the association scope doesn't work, but I think it's a rails bug: https://github.com/rails/rails/issues/13775
We use the scope approach with Rails 4.1.6 and haven't had any problems yet.
@SebastianG86 does it also work with joins and includes? i.e.
class Chapter < ActiveRecord::Base
belongs_to :book, -> { with_deleted}
end
Chapter.joins(:book)
in my case (also rails 4.1.6) I can call chapter.book
and will properly unscope :deleted_at, but when I call Chapter.joins(:book)
it won't return chapters from deleted books
Anyone has a workaround for this?
My approach is to unscope the :deleted_at in the query chain like:
belongs_to :messages_with_deleted, -> { unscope(where: :deleted_at) }, class_name: 'Message', foreign_key: :message_id
Thanks for responding on Christmas Day!
Unfortunately, your solutions doesn't work for me. Maybe because my project is still on Rails 4.0.x. But you helped me understand something that I didn't know and that redirected me to renewed Google searches.
I ended up using the abstractcoder solution presented here: http://stackoverflow.com/questions/19291181/rails-4-activerecord-includesmodel-without-its-default-scope
It's not pretty, but until the Rails team fixes https://github.com/rails/rails/issues/13775, it will have to do.
Thanks and Merry Christmas to you!.
This is still broken for me in rails 4.2, but this workaround worked for me:
has_many :foos
def foos
super.with_deleted
end
My app uses Rails 4.1.8 and neither @NicoBleh or @nornagon solutions work for me... Any update on the situation?
I ended doing...:
def course
Course.with_deleted.find(course_id)
end
EDIT
This is a bad idea, because if you do your_instance.course = Course.new
, your_instance.course
will fail because course is not persisted...
Here is a solution:
def course
Course.unscoped{ super }
end
@NicoBleh thanks!
Using the example in the README, eager loading the association doesn't work if I reference the association in a where clause.
class Person < ActiveRecord::Base
belongs_to :group, -> { with_deleted }
end
Person.includes(:group).all # works
Person.includes(:group).where(group: {id: 5}).all # doesn't work
If I reference the association in the where clause the resulting eager loading SQL adds the "deleted_at is NULL" clause to my query, which I DO NOT want.
LEFT OUTER JOIN "groups" ON "groups"."id" = "people"."group_id" AND "groups"."deleted_at" IS NULL
Is this a rails bug? Or a paranoia bug?
Looks like it's a Rails bug. Specifically https://github.com/rails/rails/pull/16531
Is there any solutions when I reference association in a where clause?
class Chapter < ActiveRecord::Base
acts_as_paranoid
# This would override the deleted scope at all times
# I believe the opened issue was intended for optionally unscoping the query
belongs_to :book, -> { with_deleted }
# As far as I can tell, this simply does not work in Rail 4.0.x
belongs_to :book_with_deleted, -> { unscope(where: :deleted_at) }, class_name: 'Book', foreign_key: :book_id
# I've found this to be the best option for my application so far.
# This method returns the Book that this Chapter belongs to, whether it was deleted or not,
# but is explicit, just like calling with_deleted on a relation.
def deleted_book
Book.with_deleted.find( self.chapter_id )
end
end
The only working solution I've found so far is to manually specify the join:
Chapter.joins('INNER JOIN "books" ON "books"."id" = "chapters"."book_id"')
Reading through the issue I don't fully understand if this is a bug in paranoia, a bug in rails, or an expected behaviour.
The linked issues for rails are closed, so I assume that's not blocking anything.
I would expect that if a record is deleted, when I access a deleted object's belongs_to
or a has_many
, I get either all records, or the deleted records.
If I have a deleted post
and I access a user post.user
, the user is nil
. with_deleted
on the association fails.
Currently I'm using a workaround like this:
# post.rb
belongs_to :post
def user
deleted? ? User.unscoped { super } : super
end
I'm using paranoia 2.3.1
and rails 5.1.2
.
Anyway, thanks for the great job your're doing here guys! 🙂
It's January 2018 (happy 4th anniversary guys!) and I just wanted to write a massive thank you to @wynksaiddestroy for the solution two comments above, nothing else but that worked!
I was in a situation with MyObject.joins(:related_deleted_objects).first
and not getting any my_objects
where the related_deleted_object
was destroyed. whew! :)
@Schwad: You're welcome. Always happy to help someone out.
I'm on Rails 5.0.7. Bellowing code works for me.
class Client
has_one :contact_detail, -> { unscope(where: :deleted_at) }
end
class ContactDetail
belongs_to :client, with_deleted: true
end
When you call Client.last.contact_detail
, it will give you deleted contact_detail
.
Is there anyone to add support for
with_deleted
for associations the same was acts_as_paranoid does so that we can query an associated model and return everything including what was deleted?