【问题标题】:Rails: Scope parent model by attribute of childRails:按子属性确定父模型的范围
【发布时间】:2018-06-27 18:23:45
【问题描述】:

我很难在 Rails 中找出一些东西。这可能与我对 SQL 的知识非常有限有关,因为我对 Rails 非常了解。我正在使用 Rails 5。

我有两个模型:申请人和申请。

class Applicant < ApplicationRecord
  has_one :application
  has_many :skills

  accepts_nested_attributes_for :application
  accepts_nested_attributes_for :skills, 
    reject_if: ->(skill) { skill[:name].empty? || skill[:experience].empty? }

  validates_with ApplicantValidator
 end

class Application < ApplicationRecord
  belongs_to :applicant
  has_many :notes

  VALID_STATUSES = ["in review", "accepted", "declined", "closed"]

  validates_length_of   :why_interested, minimum: 25
  validates             :accept_terms, acceptance: true
  validates             :status, inclusion: { in: VALID_STATUSES }

  before_validation :set_status

  private

  def set_status
    self.status ||= "in review"
  end
end

我想向申请人模型添加一个范围:active,该模型仅返回申请状态为“审查中”的申请人。但是,我找不到在作用域 proc 内访问应用程序的方法。

对于与孩子有has_many 关系的情况,我看到了其他建议,但在我的情况下它们不起作用。

我怀疑它会有所作为,但我使用的是 Postgres。我最接近的解决方案是添加它,但是当我运行 RSpec 时,它说应用程序表需要一个 FROM 子句。我不知道如何实现。

scope :active, -> { joins(:application).where('"application"."status" = "in review"') }

【问题讨论】:

  • SQL中的双引号用于引用标识符(例如表名和列名),单引号用于字符串文字,表名也是复数。你可能想说where('"applications"."status" = 'in review'') 或者更好的where(applications: { status: 'in review' }),这样ActiveRecord 就可以引用了。
  • 我将其更改为scope :active, -&gt; { joins(:application).where({ applications: { status: "in review" } }) },它不再引发错误,但范围不应该返回空。
  • 应该发现它不是什么?您也可以使用where(id: Application.select(:applicant_id).where(status: 'in review')),但这应该会为has_one 关联产生相同的结果。
  • 有趣 - 看起来第二种方式在 Rails 控制台中有效,但在 RSpec 中无效。我认为问题一定出在我的工厂。谢谢!
  • 两个版本都应该使用has_one 做同样的事情。第二个往往更适合has_many 关联,因为它避免了 JOIN 可能引入的重复。

标签: sql ruby-on-rails activerecord


【解决方案1】:
scope :in_review_applicants, -> { joins(:application).where('application.status = ?', :in_review) }

我认为是这样的..

【讨论】:

  • 这给我一个错误,上面写着PG::UndefinedTable: ERROR: missing FROM-clause entry for table "application",这与我添加的范围相同。
  • 更改应用程序的应用程序
  • 我也试过了,我得到了ActiveRecord::ConfigurationError: Can't join 'Applicant' to association named 'applications'; perhaps you misspelled it?
  • 你使用joins中的关联名,但where中的表名:joins(:application).where('applications.status = ?', :in_review)joins(:application).where(applications: { status: :in_review })
  • 你要改成表名,joins(:applications).where('applications.status..... 或者with includes { includes(:application).where(applications: { status : :in_review }).references(:applications)
猜你喜欢
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多