Активные записи отношений - кому это нужно? - PullRequest
0 голосов
/ 19 ноября 2011

Ну, я запутался в запросах рельсов. Например:

Affiche belongs_to :place
Place has_many :affiches

Мы можем сделать это сейчас:

@affiches = Affiche.all( :joins => :place )

или

@affiches = Affiche.all( :include => :place )

и мы получим много дополнительных SELECT, если будет много арифмов:

Place Load (0.2ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.3ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 3 LIMIT 1
Place Load (0.8ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 444 LIMIT 1
Place Load (1.0ms)  SELECT "places".* FROM "places" WHERE "places"."id" = 222 LIMIT 1
...and so on...

И (sic!) С :joins используется каждый SELECT удваивается!

С технической точки зрения, мы просто пишем так:

@affiches = Affiche.all( )

и результат абсолютно одинаковый! (Потому что у нас отношения объявлены). Единственным выходом для сохранения всех данных в одном запросе является удаление отношений и запись большой строки с помощью «LEFT OUTER JOIN», но все же существует проблема группировки данных в многомерном массиве и проблема с аналогичными именами столбцов, такими как id.

Что сделано неправильно? Или что я делаю не так?

UPDATE:

Ну, у меня есть эта строка Place Load (2.5ms) SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20)) и список выбираемых один за другим id. Странно, но я получаю эти отдельные выборки, когда делаю это в each scope:

 <%= link_to a.place.name, **a.place**( :id => a.place.friendly_id ) %>

отмеченная a.place - это точка, которая производит эти дополнительные запросы.

ОБНОВЛЕНИЕ 2:

И позвольте мне немного посчитать. В консоли у нас есть:

 Affiche Load (1.8ms)  SELECT affiches.*, places.name FROM "affiches" LEFT OUTER JOIN "places" ON "places"."id" = "affiches"."place_id" ORDER BY affiches.event_date DESC
 <VS>
 Affiche Load (1.2ms)  SELECT "affiches".* FROM "affiches"
 Place Load (2.9ms)  SELECT "places".* FROM "places" WHERE ("places"."id" IN (3,444,222,57,663,32,154,20))

Выходит: 1,8 мс против 4,1 мс, в значительной степени, сбивает с толку ...

1 Ответ

2 голосов
/ 19 ноября 2011

Здесь что-то действительно странное, потому что опция :include предназначена для сбора атрибута place_id с каждого афиша, а затем для извлечения всех мест сразу, используя запрос на выборку, подобный следующему:

select * from places where id in (3, 444, 222)

Вы можете проверить, чтов консоли рельсов.Просто запустите его и запустите этот фрагмент:

ActiveRecord::Base.logger = Logger.new STDOUT
Affiche.all :include => :place 

Вы можете случайно получить афиши, не включая места в вашем коде, а затем вызывая место для каждого рельса создания афиши, чтобы выполнить отдельный запрос для каждого из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...