brendon / acts_as_list

An ActiveRecord plugin for managing lists.
http://brendon.github.io/acts_as_list/
MIT License
2.05k stars 356 forks source link

Complex Scope: scope based on status attribute in polymorphic parent. #339

Closed alejorivera closed 5 years ago

alejorivera commented 5 years ago

Hi there! Thanks for creating and maintaining this wonderful piece of software.

I'm running into a roadblock. I need to create an acts_as_list scope that checks the status of an association. The case is very similar to using the paranoid gem, except the deleted_at field is not on the record itself but on an association.

Is there a way to make this work?

Thank you!!

My models look like this:

class TodoItem < ActiveRecord::Base
  belongs_to :todo_list
  has_one :recording, as: :recordable

  acts_as_list scope: :todo_list
end
class Recoding < ActiveRecord::Base
  belongs_to :recordable, polymorphic: true, dependent: :destroy

  scope :published, -> { where status: "published" }
  scope :archived, -> { where status: "archived" }
end

I think a scope similar to this would work:

scope :acts_as_list_scope, -> { where(todo_list_id: todo_list_id).joins(:recording).merge(Recording.published) }
brendon commented 5 years ago

Hi @alejorivera, I'm not 100% sure if this is possible but I'll share some code I have for one of my custom scopes:

  acts_as_list :add_new_at => :top

  def scope_condition
    ['notice_area_id = ? AND ? >= CURDATE()', notice_area_id, end_date]
  end

  # A custom acts_as_list scope requires a custom scoped_changed? method
  def scope_changed?
    changed.include?('notice_area_id') ||
    changed.include?('end_date') && (
      changes['end_date'][0] >= Time.zone.now.beginning_of_day &&
      changes['end_date'][1] < Time.zone.now.beginning_of_day ||
      changes['end_date'][1] >= Time.zone.now.beginning_of_day &&
      changes['end_date'][0] < Time.zone.now.beginning_of_day
    )
  end

  def destroyed_via_scope?
    :notice_area_id == (destroyed_by_association && destroyed_by_association.foreign_key.to_sym)
  end

I hope that helps point you in the right direction. Basically you need to override the standard scoping methods to achieve what you want :)