Как сделать объединение в ActiveRecord после того, как записи были возвращены? - PullRequest
4 голосов
/ 08 июня 2010

Я использую ActiveRecord в Rails 3 для извлечения данных из двух разных таблиц в двух разных базах данных.Эти базы данных не могут объединяться друг с другом, но мне нужно сделать простое объединение после этого.Я хотел бы сохранить отношение, чтобы я мог связать его по цепочке.

Вот упрощенная версия того, что я делаю

browsers = Browser.all # <-- this is fairly small and can reside in memory
events = Event.where(:row_date=>Date.today).select(:name, :browser_id)

Итак, как вы можете видеть, я хочуприсоединиться к browsers в отношении events, где browser_id должно равняться browsers.name.events - это отношение, и я все еще могу добавлять к нему предложения по строке, поэтому я пока не хочу выполнять запрос к БД.Как мне это сделать?

Редактировать

Для тех, кто хотел бы увидеть код для ответа, который я принял ниже, вот чтоЯ придумал:

class EventLog < ActiveRecord::Base
  belongs_to :browser

  def get_todays_events
    Event.where(:row_date=>Date.today).select(:name, :browser_id).includes(:browser)
  end
end

позволит мне получить имя браузера следующим образом

get_todays_events.browser.name

Ответы [ 2 ]

2 голосов
/ 08 июня 2010

Я бы сделал это с помощью: include. Попытка сделать это в Ruby не вызовет у вас ничего, кроме горя. Вы можете просто включить цепочку.

0 голосов
/ 24 июля 2017

joins создает соединения SQL, как и ожидалось в текущих Rails 5:

pry(main)> Customer.joins(:orders).limit(5) Customer Load (0.2ms) SELECT `customers`.* FROM `customers` INNER JOIN `orders` ON `orders`.`customer_id` = `customers`.`id` LIMIT 5 => [#<Customer:0x007fb869f11fe8 ...

Это должно быть намного быстрее, потому что требуется только один запрос к базе данных, тогда как includes будет выполнять 1 + <number of rows in first table> + <number of rows in second table>...

Вот пример, где includes требуется 1750x, пока joins:

pry(main)> benchmark do
   Order.joins(:address, :payments, :customer, :packages).all.size
> 0.02456 seconds

pry(main)> benchmark do
[14] pry(main)* Order.includes(:address, :payments, :customer, :packages).all.map(&:zip).max
[14] pry(main)*end
=> 35.607257 seconds
...