Rails, ActiveRecord: has_one, где имена столбцов совпадают - PullRequest
0 голосов
/ 11 июня 2019

У меня есть ассоциация, где project has_many steps, и я хочу найти «текущий» step для project. В таблице project хранится значение current_step, которое является step.name для текущего step.

class Project < ApplicationRecord
  # attributes: step_name:string

  has_many :steps
  has_one :current_step, -> { where("steps.name = projects.step_name") }, class_name: "Step"
end

class Step < ApplicationRecord
  # attributes: project_id:integer, name:string

  belongs_to :project
end

Я пытаюсь настроить его как ассоциацию ActiveRecord, чтобы я мог оптимизировать загрузку current_step с project и избежать проблем n+1.

Однако я получаю сообщение об ошибке:

ActiveRecord::StatementInvalid: TinyTds::Error: The multi-part identifier "projects.step_name" could not be bound.

Я немного посмотрел на SO и увидел, что другие сталкивались с этой ошибкой TinyTds, но я не совсем уверен, что это значит или как это связано с моей конкретной ситуацией.

Как выбрать current_step так, чтобы его можно было эффективно включить, чтобы избежать n+1?

1 Ответ

1 голос
/ 11 июня 2019

У вас на самом деле нет ассоциации has_one, у вас есть специальный член has_many, поэтому я бы выразил это так.Метод расширения для ассоциации steps позволит вам сделать это:

has_many :steps do
  def current
    project = proxy_association.owner
    find_by(name: project.step_name)
  end
end

proxy_association, который ActiveRecord устанавливает для ассоциаций, позволяет вам вернуться к содержащему project как proxy_association.owner.find_by внутри метода расширения будет ограничен ассоциацией.

Тогда вы можете сказать что-то вроде:

project.steps.current

, чтобы получить то, что вы ожидаете от своего has_one.

...