Rails: Why is with_exclusive_scope protected? Any good practice on how to use it?

后端 未结 3 1028
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-04 15:35

Given a model with default_scope to filter all outdated entries:

# == Schema Information
#
#  id          :integer(4)      not null, primary key
#           


        
相关标签:
3条回答
  • 2020-12-04 15:58

    Avoid default_scope if possible. I think you should really re-ask yourself why you need a default_scope. Countering a default_scope is often messier than it's worth and it should only be used in rare cases. Also, using default_scope isn't very revealing when ticket associations are accessed outside the Ticket model (e.g. "I called account.tickets. Why aren't my tickets there?"). This is part of the reason why with_exclusive_scope is protected. You should taste some syntactic vinegar when you need to use it.

    As an alternative, use a gem/plugin like pacecar that automatically adds useful named_scopes to your models giving you more revealing code everywhere. For Example:

    class Ticket < ActiveRecord::Base
      include Pacecar
      belongs_to :user
    end
    
    user.tickets.ends_at_in_future # returns all future tickets for the user
    user.tickets                   # returns all tickets for the user
    

    You can also decorate your User model to make the above code cleaner:

    Class User < ActiveRecord::Base
      has_many :tickets
    
      def future_tickets
        tickets.ends_at_in_future
      end
    end
    
    user.future_tickets # returns all future tickets for the user
    user.tickets        # returns all tickets for the user
    

    Side Note: Also, consider using a more idiomatic datetime column name like ends_at instead of end_date.

    0 讨论(0)
  • 2020-12-04 16:05

    You must encapsulate the protected method inside a model method, something like:

    class Ticket < ActiveRecord::Base
      def self.all_tickets_from(user)
        with_exclusive_scope{user.tickets.find(:all)}
      end
    end
    
    0 讨论(0)
  • 2020-12-04 16:11

    FYI for anyone looking for the Rails3 way of doing this, you can use the unscoped method:

    Ticket.unscoped.all
    
    0 讨论(0)
提交回复
热议问题