Rails:为什么with_exclusive_scope保护? 有关如何使用它的良好做法?

给定一个使用default_scope的模型来过滤所有过时的条目:

# == 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 

现在我想获得任何票。 在这种情况下, with_exclusive_scope是要走的路,但这种方法保护? 只有这个工程:

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

一种黑客,不是? 那么什么是正确的使用方式? 特别是在处理关联时,情况会变得更糟(因为用户有很多票):

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

太丑了! – 不能成为路轨!

任何寻找Rails3方式的人都可以使用unscoped方法:

 Ticket.unscoped.all 

如果可能,避免使用default_scope 。 我想你应该重新问自己,为什么你需要一个default_scope 。 反制default_scope通常比它的价值更混乱,应该只在less数情况下使用。 此外,使用default_scope在Ticket模型之外访问票据关联时不是很明显(例如“我叫account.tickets 。为什么我的票不在那里?” )。 这是为什么with_exclusive_scope受到保护的原因之一。 当你需要使用时,你应该品尝一些句法醋 。

作为替代scheme,使用像pacecar这样的gem /插件,可以自动将有用的named_scope添加到模型中,从而为您提供更多的透露代码。 例如:

 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 

注意:另外,考虑使用更惯用的date时间列名称像ends_at而不是end_date

您必须将受保护的方法封装在模型方法中,如下所示:

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