Co Choco powiedział, że będzie działać, jeśli chcesz tablicę instancji nie aktywny rekord. Jeśli chcesz aktywną instancję rekordów, wykonaj następujące czynności:
User.where(id: 5).select(:id, :first_name).take
Oto kilka dodatkowych informacji. Nie jestem pewien, ile masz/nie wiesz, więc zakładam, że wiesz mniej, niż więcej.
Zakładam, że zdajesz sobie sprawę z tego, co robisz powyżej, to jest metoda łańcuchowa - tzn. Wywołujesz metodę, a następnie wywołujesz inną metodę na wyniku pierwszej metody. Na przykład:
User.find_by(id: 5).attributes.slice('id', 'first_name')
Dzwonisz metodę find_by_id
na klasie User
. Ta metoda zwróci instancję z klasy User
(tj. Aktywną instancję rekordu). Ta instancja ma metodę o nazwie attributes
, którą wywołujesz. Metoda attributes
zwraca instancję klasy Hash
reprezentującą pola z poprzedniej aktywnej instancji rekordu. Hash
ma metodę slice
, którą wywołujemy po kolei. Metoda slice
zwraca inne wystąpienie Hash
, zawierające podzestaw określonych przez ciebie pól.
Tak więc należy jasno określić, że podczas łączenia metod nie wywołuje się każdej kolejnej metody na tej samej zasadzie - wywołuje się ją w zwracanej wartości poprzedniej metody w łańcuchu .
OK, więc z tego na drodze:
Wszystkie metody find
przeznaczone są do zapytań do bazy danych i zwróci jeden przypadek modelu aktywnego zapisu lub zwykły tablicy rubinowy zawierającego wiele instancji Active Record modele.
Wiele innych metod - select
, where
, itp., NIE trafiają od razu w bazę danych i NIE są przeznaczone do zwracania aktywnej instancji rekordu. Wszystkie zwracają instancję ActiveRecord::Relation
.Numer ActiveRecord::Relation
przypomina potencjalną grupę rekordów spełniających określone warunki - możesz dodać do niej dodatkowe warunki. To jak "zapytanie o bazę danych, które czeka, aby się wydarzyć" lub "zapytanie o bazę danych, które mogło, ale nie musiało się jeszcze wydarzyć".
Po wywołaniu metody jak where
, order
lub select
na ActiveRecord::Relation
, zwróci instancję ActiveRecord::Relation
, co oznacza, że masz instancji tej samej klasy, a może metody łańcuchowe z tej klasy ładnie np User.where(name: 'Fred').select(:id, :name).order('name ASC')
Twoje wystąpienie ActiveRecord::Relation
będzie bardzo inteligentny i nie będzie przeszkadzało trafienia bazy danych do czasu wywołania metody, która wyraźnie wskazuje, chcesz rekordy teraz - jak each
, all
, take
itp
Tak więc, poszedłem na dłużej, niż planowałem, więc zakończę. Oto kod po raz pierwszy wspomniano, z podziałem, mocno skomentował wyjaśnienie poniżej:
User.where(id: 5).select(:id, :first_name).take
złamanie go:
my_relation = User.where(id: 5)
# The database will not have been hit yet - my_relation
# is a query waiting to happen
my_second_relation = my_relation.select(:id, :first_name)
# The database has STILL not been hit.
# the relation now contains both the conditions
# from the previous my_relation, and the new 'select'
# criteria we specified
my_user = my_second_relation.take
# OK, 'take' means we want the first record
# matching all our criteria,
# so my_second_relation will hit the database
# to get it, and then return an Active Record
# instance (ie, an instance of the User class)
Wow ... poszedłem na dłużej niż oczekiwano. Mam nadzieję, że niektóre z nich były przydatne!
Jak odróżnić ** Gość ** z ** zwykły użytkownik **? – Pavan