Ruby-on-rails Rails:为什么 with_exclusive_scope 受到保护?关于如何使用它有什么好的做法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1648971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails: Why is with_exclusive_scope protected? Any good practice on how to use it?
提问by RngTng
Given a model with default_scopeto filter all outdated entries:
给定一个带有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
Now I want to get anyticket. In this case with_exclusive_scopeis the way to go, but is this method protected? Only this works:
现在我想得到任何票。在这种情况下with_exclusive_scope是要走的路,但是这种方法是否受到保护?只有这样有效:
Ticket.send(:with_exclusive_scope) { find(:all) }
Kind of a hack, isn't? So what's the right way to use? Especially when dealing with associations, it's getting even worse (given a user has many tickets):
有点像黑客,不是吗?那么正确的使用方法是什么呢?特别是在处理关联时,情况变得更糟(假设用户有很多票):
Ticket.send(:with_exclusive_scope) { user.tickets.find(:all) }
That's sougly!!! - can't be the rails-way!?
这是如此丑陋!- 不可能是铁轨!?
回答by brad
FYI for anyone looking for the Rails3 way of doing this, you can use the unscopedmethod:
仅供寻找 Rails3 方法的任何人使用,您可以使用以下unscoped方法:
Ticket.unscoped.all
回答by Ryan McGeary
Avoid default_scopeif possible.
I think you should really re-ask yourself why you need a default_scope. Countering a default_scopeis often messier than it's worth and it should only be used in rare cases. Also, using default_scopeisn'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_scopeis protected. You should taste some syntactic vinegarwhen you need to use it.
避免default_scope如果可能的话。我认为您真的应该重新问自己为什么需要default_scope. 反击 adefault_scope通常比它的价值更混乱,它应该只在极少数情况下使用。此外,default_scope当在 Ticket 模型之外访问票证关联时, using并不是很有启发性(例如,“我打电话了account.tickets。为什么我的票不在那里?”)。这with_exclusive_scope是受到保护的部分原因。当你需要使用它时,你应该品尝一些语法醋。
As an alternative, use a gem/plugin like pacecarthat automatically adds useful named_scopes to your models giving you more revealing code everywhere. For Example:
作为替代方案,使用像pacecar这样的gem/插件,它会自动将有用的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
You can also decorate your User model to make the above code cleaner:
你还可以装饰你的 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
Side Note: Also, consider using a more idiomatic datetime column name like ends_atinstead of end_date.
旁注:另外,请考虑使用更惯用的日期时间列名称,ends_at而不是end_date.
回答by Vlad Zloteanu
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

