Porównaj ceny domen i usług IT, sprzedawców z całego świata

Tworzenie klauzuli Rails ActiveRecord where


Jaki jest najlepszy sposób na skonstruowanie klauzuli Where przy użyciu Rails ActiveRecord? Na przykład załóżmy, że mam akcję kontrolera, która zwraca listę postów na blogu:
def index
@posts = Post.all
end

Załóżmy teraz, że chcę móc przekazać parametr url, aby ta akcja kontrolera zwracała tylko posty od określonego autora:
def index
author_id = params[:author_id] if author_id.nil?
@posts = Post.all
else
@posts = Post.where("author = ?", author_id)
end
end

Nie bardzo mi się to podoba. Gdybym dodał porządkowanie lub paginację lub, co gorsza, bardziej opcjonalne parametry ciągu zapytania URL do filtrowania, ta akcja kontrolera stałaby się bardzo złożona.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Co powiesz na:
def index
author_id = params[:author_id] @posts = Post.scoped @post = @post.where(:author_id => author_id) if author_id.present? @post = @post.where(:some_other_condition => some_other_value) if some_other_value.present?
end

Post.scoped
jest zasadniczo leniwym ładowanym odpowiednikiem Post.all (ponieważ Post.all natychmiast zwraca tablicę , podczas gdy Post.scoped po prostu zwraca obiekt relacji). To żądanie nie zostanie wykonane do
naprawdę nie będziesz próbował powtórzyć tego w widoku (wywołując .each).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mmmm, najlepszym podejściem, jakie chcesz zastosować, może być rozłożenie tego w dwóch krokach
def index
@post = Post.all
enddef get
@post = Post.where("author=?", params[:author_id])
end

IMHO ma to większy sens, jeśli myślisz o RESTful API, indeks oznacza wypisanie wszystkiego i pobranie (lub pokazanie), aby otrzymać żądanie i pokazać to!
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To pytanie jest dość stare, ale wciąż rośnie w Google w 2019 roku, a także niektóre z wcześniejszych odpowiedzi są nieaktualne, więc postanowiłem podzielić się możliwym rozwiązaniem.
Niektóre obszary są wprowadzane do modelu ze sprawdzeniem istnienia przekazanego parametru:
class Post
scope :where_author_ids, ->(ids){ where(author_id: ids.split(‘,’)) if ids }
scope :where_topic_ids, ->(ids){ where(topic_id: ids.split(‘,’)) if ids }

Następnie w kontrolerze możesz po prostu umieścić tyle filtrów, ile chcesz, na przykład:
def list
@posts = Post.where_author_ids(params[:author_ids])
.where_topic_ids(params[:topic_ids])
.where_other_condition_ids(params[:other_condition_ids])
.order(:created_at)

Parametr może wtedy być pojedynczą wartością lub listą wartości oddzielonych przecinkami, z których obie działają poprawnie.
Jeśli parametr nie istnieje, po prostu pomija tę klauzulę where i nie filtruje pod kątem tego konkretnego kryterium. Jeśli parametr istnieje, ale jego wartość jest pustym ciągiem, to wszystko będzie „filtrować”.
Oczywiście ta decyzja nie będzie pasować do wszystkich okoliczności. Jeśli masz stronę widoku z włączonymi wieloma filtrami, ale kiedy po raz pierwszy ją otworzysz, chcesz pokazać wszystkie swoje dane, a nie żadne dane, dopóki nie naciśniesz przycisku przesyłania lub czegoś podobnego (tak jak zrobiłby to ten kontroler), musisz trochę go podkręcić.
Próbowałem wstrzyknąć to w SQL i railsy wydają się dobrze radzić sobie z utrzymaniem wszystkiego w bezpiecznym miejscu, o ile widzę.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Czy coś takiego zadziała?
def get
raise "Bad parameters...why are you doing this?" unless params[:filter].is_a?(Hash)
@post = Post.where(params[:filter])
end

Następnie możesz zrobić coś takiego:
? filter [author_id] = 1 & amp; filter [post_date] = ... i tak dalej.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Należy modelować adres URL przy użyciu zagnieżdżonych zasobów. Oczekiwany adres URL to/autorów/1/posty. Pomyśl o autorach jak o zasobach. Przeczytaj o zagnieżdżonych zasobach w tym przewodniku:

http://guides.rubyonrails.org/routing. html
http://guides.rubyonrails.org/routing.html
(przewiń w dół do zasobów zagnieżdżonych 2,7).

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się