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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:54:10  来源:igfitidea点击:

Rails: Why is with_exclusive_scope protected? Any good practice on how to use it?

ruby-on-railsscope

提问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