Проблема таблицы соединений Rails - PullRequest
2 голосов
/ 09 октября 2010

Я работаю над проектом rails и у меня возникли некоторые проблемы со следующим объединением:

@page = Page.find(params[:id], :joins => "LEFT JOIN page_translations ON page_translations.page_id = pages.id")

По какой-то причине он только вытягивает все из таблицы Pages.

Вотмоя модель для Page

class Page < ActiveRecord::Base
  has_many :users_pages
  has_many :users, :through => :users_pages
  has_many :page_translations
  has_many :categories
  accepts_nested_attributes_for :page_translations
  accepts_nested_attributes_for :categories
end

Вот моя модель для PageTranslation

class PageTranslation < ActiveRecord::Base
  belongs_to :pages
end

Заранее благодарен за помощь!

Редактировать (@thenduks)

Журнал выполняет два отдельных запроса:

Page Load (0.5ms)  SELECT `pages`.* FROM `pages` WHERE (`pages`.`id` = 1) LIMIT 1

PageTranslation Load (0.5ms) SELECT `page_translations`.* FROM `page_translations` WHERE (`page_translations`.page_id = 1)

Вот как выглядит мой контроллер:

@page = Page.find(params[:id], :include => :page_translations)

Ответы [ 2 ]

2 голосов
/ 09 октября 2010

Я был поставлен в тупик из-за этого и потратил несколько часов, пытаясь понять это. Оказывается, использование метода joins интерфейса запросов не инициализирует модели, связанные с объединяемыми таблицами. Это можно увидеть, посмотрев операторы SQL на консоли сервера или даже перенаправив запись ActiveRecord в STDOUT на консоли Rails.

Я был очень разочарован этим. Просто не похоже, как должен работать joins метод - это, конечно, не то, что я ожидал. Я ожидал, что он будет загружаться, так как он находился в разделе «Загрузка» в Edge Guides.

Во всяком случае, я не мог тратить больше времени на попытки выяснить это, поэтому вместо этого я использовал необычный интерфейс запроса, чтобы просто построить мой запрос, используя to_sql, чтобы получить SQL для моего запроса, а затем передал SQL в select_all, который возвращает массив хэшей, где каждый элемент в массиве (каждый хэш) представляет строку.

Пример:

query = Post.joins("LEFT JOIN categories ON post.category_id = categories.id")
query.select("posts.*, category.category_name")
con = ActiveRecord::Base.connection
results = con.select_all(query.to_sql)

Результаты:

[{"id": 1, "title": "joins, why have you forsaken me", "category_name": "frustration"},{"id": 2, "title": "pizza", "category_name": "food"}]

Честно говоря, я все же хотел бы знать наверняка, возможно ли сделать это так, как мы думаем , как оно должно работать, или как должно работать. В противном случае я не вижу причин для использования метода joins, кроме как для того, чтобы помочь нам построить запрос. Так что если кто-нибудь из Rails-гуру знает, как использовать joins для заполнения моделей, связанных с этими таблицами, ПОЖАЛУЙСТА, ДАЙТЕ МНЕ (США) ЗНАТЬ!

Во всяком случае, я надеюсь, что это поможет вам двигаться вперед.


ОБНОВЛЕНИЕ : Так что я думаю, что только что понял. Я наткнулся на это сообщение в блоге . Как выясняется, при использовании метода joins интерфейса запроса Rails фактически добавит столбцы, выбранные вами из объединенных таблиц, в качестве атрибута методов модели, к которой присоединяется.

Используя тот же пример, что и выше, я могу получить доступ к category_name каждого сообщения, просто позвонив post.category_name. # $%! Невероятно просто, но никакой документации по этому поводу нет!

Вот еще раз:

query = Post.joins("LEFT JOIN categories ON post.category_id = categories.id")
query.select("posts.*, category.category_name")
posts = query.all

# access a post's category name
puts posts[0].category_name

# this is what I thought I would be able to do
# without Rails making another query to the database
puts posts[0].category.category_name

Надеюсь, это поможет! :)

0 голосов
/ 09 октября 2010

Как насчет:

Page.find( params[:id], :include => :page_translations )

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

Хорошо, поэтому в последнее время поведение ActiveRecord, когда дело доходит до соединений / включений, похоже, изменилось. В руководствах по-прежнему говорится о возможности сделать это через две ассоциации, как в has_many :orders, :include => :line_items и аналогичных ... но в том числе и записи из has_many ... После консультации с коллегой мы столкнулись некоторая информация по теме . Кажется, что одиночные монолитные запросы становились слишком сложными и уродливыми, и это вызывало проблемы с некоторыми изящными тонкостями, которые ActiveRecord предоставляет вам, и дублирующими строками, такого рода вещи.

TL; DR: Это больше не работает. Ожидается 2 запроса.

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