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