导轨:为什么with_exclusive_scope保护? 关于如何使用它的任何好的做法?(Ra

2019-09-02 13:34发布

考虑到与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) }

这是如此的丑陋! - 不能轨道路!?

Answer 1:

FYI为寻找这样的Rails3中的方式,你可以使用unscoped方法:

Ticket.unscoped.all


Answer 2:

避免default_scope如果可能的话 。 我想你应该重新问自己,为什么你需要一个default_scope 。 打击一个default_scope往往梅西耶比它的价值,它应该只在极少数情况下使用。 此外,使用default_scope当票协会的门票模型外部访问是不是很说明问题(如“我叫account.tickets 。为什么我的票吗?”)。 这就是为什么部分原因with_exclusive_scope保护。 你应该品尝语法醋当你需要使用它。

作为替代方案,使用像宝石/插件pacecar自动添加有用named_scopes到模型中处处给你更多的启发代码。 例如:

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

边注:此外,可以考虑使用更地道datetime列名状ends_at而不是end_date



Answer 3:

你必须封装模型方法中的保护方法,是这样的:

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


文章来源: Rails: Why is with_exclusive_scope protected? Any good practice on how to use it?