如果我正确理解has_one
,则外键在相关记录上。这意味着我可以在"外国"侧。当我使用has_one
记录获取相关记录时,如何确定将返回哪个记录?
以下是一个例子:
class Job < ActiveRecord::Base
has_one :activity_state
end
class ActivityState < ActiveRecord::Base
belongs_to :job
end
我们假设activity_states
表中有2行将其外键设置为作业#1
ActivityState.where(job_id: 1).select(:id, :job_id)
#=> [#<ActivityState id: 1, job_id: 1>, #<ActivityState id: 2, job_id: 1]
当我尝试从JobRequest获取activity_state
时,如何确定返回哪一个?
JobRequest.find(1).activity_state
#=> #<ActivityState id: 1, job_id: 1>
现在,看起来它正在返回它找到的第一个。
如果我想要返回最新创建的
,该怎么办?答案 0 :(得分:4)
正如评论中所讨论的,主要问题是您的系统正在为每个作业创建多个ActivityState
个对象。正如您所提到的,您的原始代码是这样做的:
ActivityState.create(job_id: @job.id)
问题是旧的ActivityState
仍包含该作业的job_id
。因此,当您执行@job.activity_state
时,您确实看到了第一个(和旧的)活动状态,因为它是数据库中的第一个。具体来说,has_one
关系执行LIMIT 1
sql子句,所以从技术上来说,&#34; first&#34;记录取决于您的数据库是否订购记录(通常按输入顺序)
通常,对于has_one
关系,如果你要做
@job.activity_state = ActivityState.new(...activity state params...)
Rails尝试强制执行每个记录的一个关联&#34;通过重置&#34; old&#34;关联记录的job_id
列为null。您的原始代码无意中绕过了执法。如果您将其更改为此代码行,您将允许Rails发挥其魔力并确保与您的关联一致的行为。
答案 1 :(得分:3)
在这种情况下你应该有一个has_many关联。要根据列返回特定记录,请创建方法。
class Job < ActiveRecord::Base
has_many :activity_states
def latest_activity_state
self.activity_states.order("updated_at ASC").last # or created_at, depends
end
end