使用带有.last的作用域在视图中返回AssociationRelation

时间:2015-02-11 16:53:46

标签: ruby-on-rails activerecord

客户有很多状态。要获得最新状态,我在Status上使用以下范围。

scope :latest, -> { order(:created_at).last }

这在Rails控制台中按预期工作。

client = Client.last
client.statuses.latest
=> #<Status id:...
client.statuses.latest.stage
=> 1

但是,它在视图中无法正常工作。 (这是f.objectClient对象的动态表单的一部分。

<%= f.object.statuses.latest.inspect %>

这将按预期返回Status个对象:#<Status id:...

但是如果我现在尝试访问对象上的属性<%= f.object.statuses.latest.stage %>,我会收到以下错误。

undefined method `stage' for #<ActiveRecord::AssociationRelation []>

这引起了我的兴趣,因为它应该是Status对象。令我困惑的是,如果我尝试一个不存在的属性,例如<%= f.object.statuses.latest.foobar %>,我会收到以下错误。

undefined method `foobar' for #<Status:0x007ff615fcdb28>

更新

我尝试将Client对象设置为控制器中的实例变量进行测试,并且按预期工作。只有在通过表单对象访问Client时才会出现此问题。

这是一个错误还是某种限制?不管怎么说呢?

更新2

找到解决此问题的方法。

<%= f.object.statuses.latest.stage unless f.object.statuses.latest.blank? %>

我不明白为什么会这样,因为最新的不是空白并返回一个舞台,所以如果有人能解释它将不胜感激。

1 个答案:

答案 0 :(得分:3)

请注意所有范围方法将返回 ActiveRecord :: Relation

我会像这样重构你的模型来解决这个问题并且仍然可以获得相同的功能。

 class Status < ActiveRecord::Base
    ....
    scope :newest, -> { order(:created_at) }

    def self.latest
       Status.newest.first
    end
 end

你应该可以打电话

client = Client.last
client.statuses.latest