Rails: dlaczego z exclusive scope jest chroniony? Jakieś dobre praktyki, jak z niego korzystać?
Podany model z default_scope do filtrowania wszystkich nieaktualnych wpisów:
# == 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
Teraz chcę dostaćdowolny bilet. W tym przypadku with_exclusive_scope jest droga, ale czy ta metoda jest chroniona? Tylko to działa:
Ticket.send(:with_exclusive_scope) { find(:all) }
Niezły hack, co? Więc jaki jest właściwy sposób użycia? Szczególnie w przypadku asocjacji jest jeszcze gorzej (biorąc pod uwagę, że użytkownik ma wiele biletów): {]}
Ticket.send(:with_exclusive_scope) { user.tickets.find(:all) }
That ' sso Brzydula!!! - nie może być rails-way!?
3 answers
Dla każdego, kto szuka sposobu Rails3, możesz użyć metody unscoped
:
Ticket.unscoped.all
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-07 20:38:05
Unikać default_scope
jeśli to możliwe .
Myślę, że powinieneś ponownie zadać sobie pytanie, dlaczego potrzebujesz default_scope
. Przeciwstawienie a default_scope
jest często bardziej kłopotliwe niż jest warte i powinno być stosowane tylko w rzadkich przypadkach. Ponadto użycie default_scope
nie jest zbyt odkrywcze, gdy połączenia biletów są dostępne poza Modelem biletu(np. " zadzwoniłem account.tickets
. Dlaczego nie ma tam moich biletów?"). Jest to jeden z powodów, dla których with_exclusive_scope
jest chroniony. Powinieneś skosztować octu syntaktycznego, gdy potrzebujesz użyj go.
Jako alternatywę, użyj gem / plugin jak pacecar , który automatycznie dodaje przydatne named_scopes do modeli dając Ci bardziej odkrywczy kod wszędzie. Na Przykład:
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
Możesz również ozdobić swój model użytkownika, aby powyższy kod był czystszy:
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
Uwaga: rozważ również użycie bardziej idiomatycznej nazwy kolumny datetime, takiej jak ends_at
zamiast end_date
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-30 13:05:03
Musisz zamknąć metodę protected wewnątrz metody modelowej, coś w stylu:
class Ticket < ActiveRecord::Base
def self.all_tickets_from(user)
with_exclusive_scope{user.tickets.find(:all)}
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-30 10:25:43