Reputation: 1079
A Client has many Statuses. To get the latest status I'm using the following scope on Status
.
scope :latest, -> { order(:created_at).last }
This works as expected in the Rails Console.
client = Client.last
client.statuses.latest
=> #<Status id:...
client.statuses.latest.stage
=> 1
However, it doesn't work as expected in the view. (This is part of a dynamic form where f.object
is a Client
object).
<%= f.object.statuses.latest.inspect %>
This returns a Status
object as expected: #<Status id:...
But if I now try to access an attribute on the object, <%= f.object.statuses.latest.stage %>
I get the following error.
undefined method `stage' for #<ActiveRecord::AssociationRelation []>
Which has thrown me, because it should be a Status
object. Adding to my confusion, if I try a nonexistent attribute, such as <%= f.object.statuses.latest.foobar %>
, I get the following error.
undefined method `foobar' for #<Status:0x007ff615fcdb28>
Update
I tried setting a Client
object as an instance variable in the controller to test, and it works as expected. This problem only seems to happen when accessing the Client
through the form object.
Is this a bug or some kind on limitation? Anyway around it?
Update 2
Found a way to fix this.
<%= f.object.statuses.latest.stage unless f.object.statuses.latest.blank? %>
I don't understand why this works, because latest isn't blank and returns a stage, so if anyone can explain it would be appreciated.
Upvotes: 4
Views: 2655
Reputation: 3940
Please note that All scope methods will return an ActiveRecord::Relation.
I would refactor your model like this to get around this and still get the same functionality.
class Status < ActiveRecord::Base
....
scope :newest, -> { order(:created_at) }
def self.latest
Status.newest.first
end
end
And you should be able to just call
client = Client.last
client.statuses.latest
Upvotes: 3