Mam powiązanie, które wymaga kilku sprzężeń/niestandardowych zapytań. Podczas próby ustalenia, jak to wdrożyć, powtarzana odpowiedź to finder_sql
. Jednak w Rails 4.2 (i nowszych):Ma wiele "finder_sql" Zamiennik w Railsach 4.2
ArgumentError: Unknown key: :finder_sql
mojej kwerendy zrobić wygląd złączyć tak:
'SELECT DISTINCT "tags".*' \
' FROM "tags"' \
' JOIN "articles_tags" ON "articles_tags"."tag_id" = "tags"."id"' \
' JOIN "articles" ON "article_tags"."article_id" = "articles"."id"' \
' WHERE articles"."user_id" = #{id}'
Rozumiem, że można to osiągnąć poprzez:
has_many :tags, through: :articles
jednak jeśli liczność łączenia jest duża (np. użytkownik ma tysiące artykułów - ale system ma tylko kilka znaczników), to wymaga załadowania wszystkich artykułów/tagów:
SELECT * FROM articles WHERE user_id IN (1,2,...)
SELECT * FROM article_tags WHERE article_id IN (1,2,3...) -- a lot
SELECT * FROM tags WHERE id IN (1,2,3) -- a few
I oczywiście ciekawy również ogólny przypadek.
Uwaga: próbował również przy użyciu składni proc, ale nie może się zorientować, że spośród:
has_many :tags, -> (user) {
select('DISTINCT "tags".*')
.joins('JOIN "articles_tags" ON "articles_tags"."tag_id" = "tags"."id"')
.joins('JOIN "articles" ON "article_tags"."article_id" = "articles"."id"')
.where('"articles"."user_id" = ?', user.id)
}, class_name: "Tag"
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column tags.user_id does not exist
SELECT DISTINCT "tags".* FROM "tags" JOIN "articles_tags" ON "articles_tags"."tag_id" = "tags"."id" JOIN "articles" ON "article_tags"."article_id" = "articles"."id" WHERE "tags"."user_id" = $1 AND ("articles"."user_id" = 1)
To wygląda na to, że stara się wstrzyknąć user_id
na znaczniki automatycznie (i że kolumna istnieje tylko w artykułach). Uwaga: Wstępnie ładuję dla wielu użytkowników, więc nie mogę używać user.tags
bez innych poprawek (wklejony kod SQL jest tym, co widzę, używając tego samego!). Myśli?
gdzie piszesz to 'has_many: tags, -> (użytkownik) ...'? W user.rb? – Sajan
@sajan correct - in 'user.rb'. – Stussa