首页 > 解决方案 > Rails,ActiveRecord:列名匹配的 has_one

问题描述

我有一个关联,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_stepproject避免出现n+1问题。

但是,我不断收到错误消息:

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

我做了一些查看 SO 并看到其他人遇到了这个 TinyTds 错误,但我不完全确定它的含义或它与我的特定情况有何关系。

如何选择current_step这样可以有效地避免n+1

标签: ruby-on-railsrails-activerecordtiny-tds

解决方案


你并没有真正的has_one协会,你有一个特殊的成员,has_many所以我会这样表达。关联的扩展方法steps可以让你做到这一点:

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

ActiveRecord 为关联设置的proxy_association允许您回溯到包含projectas proxy_association.owner。扩展方法的find_by内部将被限定为关联。

然后你可以这样说:

project.steps.current

得到你期望你has_one做的事情。


推荐阅读