Given a model Post that has_many attachments, and an attachment has a hidden flag. Throughout the app I want to easily say post.attachments and only get the visible ones, so i setup a default scope in the Attachment model (using squeel):
default_scope -> { where { (hidden != true) | (hidden == nil) } }
But the admin page needs to be able to see all attachments for a post, not just the visible ones (so you can toggle the hidden checkbox). The default way of doing this (in admin/posts.rb) uses the default_scope and only lets me edit the visible ones:
f.has_many :attachments do |a|
...
end
I know I could just not use default_scope and instead name it :visible, and then everywhere (except the admin page) say post.attachments.visible but I prefer not having the do that.
How can I unscope the children attachments on the admin page?
Here's the solution I worked out:
In app/admin/posts.rb
f.has_many :attachments, for: [:attachments, f.object.attachments_including_hidden] do |a|
...
end
And in app/models/posts.rb
def attachments_including_hidden
Attachment.unscoped.where( attachable_id: id )
end
(where Attachment model belongs_to: :attachable, polymorphic: true )
What's going on? ActiveAdmin uses Formtastic, which uses Rails Form Builder. The form.has_many method is an ActiveAdmin method, which calls Formtastic's form.inputs, which in turn calls Rails' fields_for. The :for option will get passed all the way down the fields_for, which can take a collection (as its 2nd arg) so I deliver this collection to it explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With