Jak mogę powiedzieć Activerecord, aby nie ładowało kolumn typu "blob", chyba że wyraźnie zażądano? W moim starym DB jest sporo dużych bloków, które muszą być wykluczone dla "normalnych" obiektów.Zatrzymaj Activerecord od ładowania Blob kolumna
Odpowiedz
Wierzę, że można zapytać AR załadować konkretne kolumny w inwokacji do znalezienia:
MyModel.find(id, :select => 'every, attribute, except, the, blobs')
Jednak byłoby to muszą być aktualizowane w miarę dodawania kolumn, więc nie jest idealny. Nie sądzę, że istnieje sposób, aby wyraźnie wyłączyć jedną kolumnę w szynach (ani w pojedynczym wyborze SQL).
Chyba można napisać tak:
MyModel.find(id, :select => (MyModel.column_names - ['column_to_exclude']).join(', '))
przetestować przed wziąć za to moje słowo chociaż. :) Odpowiedź
FD jest w większości rację, ale ActiveRecord doesn't currently accept an array jako: wybierz argumentu, więc trzeba dołączyć odpowiednie kolumny na ciąg rozdzielany przecinkami, tak jak poniżej:
desired_columns = (MyModel.column_names - ['column_to_exclude']).join(', ')
MyModel.find(id, :select => desired_columns)
Czysty podejście nie wymaga zmian w sposobie twój kod gdzie indziej w aplikacji, czyli nie brudząc z :select
opcji
z jakiegoś powodu trzeba albo zdecydować się na sklepowych bąble w bazach danych. Nie chcesz jednak mieszać kolumn typu "blob" w tej samej tabeli, co regularne atrybuty, które mają . BinaryColumnTable pomaga przechowywać WSZYSTKIE obiekty BLOB w oddzielnej tabeli, zarządzanej w sposób przezroczysty przez model ActiveRecord. Opcjonalnie pomaga w zapisywaniu typu zawartości obiektu typu blob.
Użycie jest proste
Member.create(:name => "Michael", :photo => IO.read("avatar.png"))
#=> creates a record in "members" table, saving "Michael" into the "name" column
#=> creates a record in "binary_columns" table, saving "avatar.png" binary into "content" column
m = Member.last #=> only columns in "members" table is fetched (no blobs)
m.name #=> "Michael"
m.photo #=> binary content of the "avatar.png" file
po prostu wpadł na to za pomocą szyny 3.
Na szczęście nie było to trudne do rozwiązania. Ustawiłem default_scope
, który usunął konkretne kolumny, których nie chciałam od wyniku. Na przykład w modelu, który miałem, było pole tekstowe xml, które mogło być dość długie, a nie było używane w większości widoków.
default_scope select((column_names - ['data']).map { |column_name| "`#{table_name}`.`#{column_name}`"})
Zobaczysz z roztworu że musiałem mapować kolumn w pełni wykwalifikowani wersje abym mógł nadal korzystać z modelu poprzez relacje bez dwuznaczności w atrybutach. Później, gdy chcesz mieć pole, po prostu przylepsz na innym .select(:data)
, aby je zawierał.
Cześć Crish. Stworzyłem [wtyczkę Railsową opartą na twoim pomyśle o nazwie 'lazy_columns'] (https://github.com/jorgemanrubia/lazy_columns). Dzięki! – jmanrubia
Należy pamiętać, że to nie działa, gdy używana jest opcja: include – Christian
FYI, zobaczyłem to na mojej konsoli po użyciu: DEPRECATION OSTRZEŻENIE: Wywołanie #default_scope bez bloku jest przestarzałe. Na przykład zamiast 'default_scope gdzie (color: 'red')', użyj 'default_scope {where (color: 'red')}'. (Alternatywnie możesz po prostu przedefiniować self.default_scope.) –
Naprawiono drugą sugestię, zgodnie z obserwacją Zeke'a. Dzięki @Zeke. –