代码之家  ›  专栏  ›  技术社区  ›  RngTng

Rails:为什么要保护专用范围?关于如何使用它有什么好的做法吗?

  •  44
  • RngTng  · 技术社区  · 16 年前

    给定一个模型 默认范围 要筛选所有过期条目:

    # == Schema Information
    #
    #  id          :integer(4)      not null, primary key
    #  user_id     :integer(4)      not null, primary key
    #  end_date    :datetime        
    
    class Ticket < ActiveRecord::Base
      belongs_to :user
      default_scope :conditions => "tickets.end_date > NOW()"
    end
    

    现在我想 任何 票。在这种情况下 带专用范围 是要走的路吗,但是这个方法受保护吗?只有这样才能工作:

     Ticket.send(:with_exclusive_scope) { find(:all) }
    

    有点像黑客,不是吗?那么,正确的使用方法是什么?尤其是在处理关联时,情况变得更糟(如果用户有很多票):

     Ticket.send(:with_exclusive_scope) { user.tickets.find(:all) }
    

    那是 所以 丑陋!!!!-不能走铁轨!?

    3 回复  |  直到 15 年前
        1
  •  167
  •   brad    15 年前

    仅供参考,对于任何寻找铁路3方法的人,您可以使用 unscoped 方法:

    Ticket.unscoped.all
    
        2
  •  33
  •   Ryan McGeary    16 年前

    避免 default_scope 如果可能的话 . 我觉得你应该重新问问自己为什么你需要 默认范围 . 反A 默认范围 往往比它的价值更混乱,它应该只在很少的情况下使用。此外,使用 默认范围 当在票务模型之外访问票务关联时(例如 “我打电话来了 account.tickets . 为什么我的票不在那里?” )这也是为什么 with_exclusive_scope 受到保护。你应该尝尝 syntactic vinegar 当你需要使用它的时候。

    作为替代方案,使用gem/plugin-like pacecar 这会自动将有用的命名范围添加到您的模型中,从而使您在任何地方都能看到更多的代码。例如:

    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
    

    您还可以修饰您的用户模型以使上述代码更清晰:

    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
    

    另一个注意事项是,考虑使用更惯用的日期时间列名称,比如 ends_at 而不是 end_date .

        3
  •  20
  •   Vlad Zloteanu    16 年前

    必须在模型方法中封装受保护的方法,例如:

    class Ticket < ActiveRecord::Base
      def self.all_tickets_from(user)
        with_exclusive_scope{user.tickets.find(:all)}
      end
    end