Ответ 1
FYI для тех, кто ищет способ Rails3 этого, вы можете использовать метод unscoped
:
Ticket.unscoped.all
Для модели с параметром 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
Теперь я хочу получить билет. В этом случае с_exclusive_scope это путь, но защищен ли этот метод? Только это работает:
Ticket.send(:with_exclusive_scope) { find(:all) }
Вид взлома, не так ли? Итак, какой правильный способ использовать? Особенно при работе с ассоциациями это становится еще хуже (учитывая, что у пользователя много билетов):
Ticket.send(:with_exclusive_scope) { user.tickets.find(:all) }
Это так уродливо!!! - не может быть рельсовым способом!?
FYI для тех, кто ищет способ Rails3 этого, вы можете использовать метод unscoped
:
Ticket.unscoped.all
Избегайте default_scope
, если возможно.
Я думаю, вы действительно должны спросить себя, зачем вам нужен default_scope
. Противодействие default_scope
часто беспорядочно, чем стоит, и его следует использовать только в редких случаях. Кроме того, использование default_scope
не очень показательно, когда доступ к ассоциациям билетов осуществляется за пределами модели Ticket (например, "Я назвал account.tickets
. Почему у меня нет билетов?" ). Это является одной из причин, по которым защита with_exclusive_scope
защищена. Вы должны попробовать синтаксический уксус, когда вам нужно его использовать.
В качестве альтернативы используйте gem/plugin, такой как 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
Вы также можете украсить свою модель 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
.
Вы должны инкапсулировать защищенный метод внутри метода модели, например:
class Ticket < ActiveRecord::Base
def self.all_tickets_from(user)
with_exclusive_scope{user.tickets.find(:all)}
end
end