2014-05-01 19 views
8

Ulepszanie szyn 3.2. do szyn 4. Mam następujący zakres:Szyny 4 zakres z argumentem

# Rails 3.2 
scope :by_post_status, lambda { |post_status| where("post_status = ?", post_status) } 
scope :published, by_post_status("public") 
scope :draft, by_post_status("draft") 

# Rails 4.1.0 
scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) } 

Ale nie mogłem się dowiedzieć, jak wykonać drugą i trzecią linię. Jak mogę utworzyć inny zakres z pierwszego zakresu?

Odpowiedz

17

bardzo proste, wystarczy sama lambda bez argumentów:

scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) } 
scope :published, -> { by_post_status("public") } 
scope :draft, -> { by_post_status("draft") } 

lub bardziej zwarte:

%i[published draft].each do |type| 
    scope type, -> { by_post_status(type.to_s) } 
end 
3

Z Rails edge docs

„Rails 4.0 wymaga, aby zakresy użyć obiekt wywoływany, taki jak Proc lub lambda: "

scope :active, where(active: true) 

# becomes 
scope :active, -> { where active: true } 


Mając to na uwadze, można łatwo przerobić twój kod jako takie:

scope :by_post_status, lambda { |post_status| where('post_status = ?', post_status) } 
scope :published, lambda { by_post_status("public") } 
scope :draft, lambda { by_post_status("draft") } 

W przypadku, że masz wiele różnych stanach, które chcesz wspierać i znaleźć To może być uciążliwe, dla Ciebie mogą być następujące:

post_statuses = %I[public draft private published ...] 
scope :by_post_status, -> (post_status) { where('post_status = ?', post_status) } 

post_statuses.each {|s| scope s, -> {by_post_status(s.to_s)} } 
+0

Co to jest różnica między metodą a zakresem. Mam na myśli, jeśli chcesz na przykład ograniczyć liczbę użytkowników, możesz to zrobić według metody lub zakresu, prawda? Czy w tym przypadku najlepszym sposobem jest użycie zakresu zamiast metody? –