model: `last` method always returns a hash

I have the following repository:

class PostRepository < Hanami::Repository
  def newest_post
     root.order(:created_at).as(:entity).last
  end
end

The newest_post method will always return a Hash instead of an Post instance. If I change last to first, I get a Post instance as I want.

I have no clue where to start looking for the problem. If someone could give me a clue, I can try to fix this one myself.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 24 (20 by maintainers)

Commits related to this issue

Most upvoted comments

FYI we started working on rom-4 and I already ported auto-map/struct feature from repository to rom core and now this works consistently:

[5] pry(main)> users = rom.relations[:users]
[6] pry(main)> users.with(auto_struct: true).first
=> #<ROM::Struct::User id=1 name="Joe Dane">
[7] pry(main)> users.with(auto_struct: true).last
=> #<ROM::Struct::User id=1 name="Joe Dane">

This means that hanami will be able to enable auto-map/struct for its relations and it’ll work consistently.

Furthermore, you’ll be able to rely on built-in rom structs, as we added a feature where you can provide your own namespace and base struct class, which will be used to infer structs automatically and use your struct class as the base. You’ll be able to either rely on inferred attributes, or define them explicitly, up to you.

@davydovanton we have one and one! so:

users.one # returns first struct based on default by-pk sorting
users.reverse.one # returns last struct based on default by-pk sorting

FWIW I don’t think that having first and last is a good practice, I know it’s common because it exists in Array and popular ORMs provide it too, the problem is that you can’t really tell what the order is, and you can’t possibly expect to get consistent results when order is not enforced in any way. Personally I see this is as a weird antipattern that we’ve happily adopted 😦

This won’t be fixed in rom because it’s not a bug in rom. See here for more info.

@cllns I assigned this to you as you’re working on the documentation for this. Can we get a PR out in a couple of days? Thank you!

Folks, I went straight with the refactoring regarding Repository#first and #last, as you suggested. See https://github.com/hanami/model/commit/57377946bcc0bf13e4a947309ac4c90add0cb283

The reason why this is a good idea is simple: it removes Sequel from the implementation of #last. See the commit diff.


But please note that this GH issue is NOT about Repository#first and #last, as they already return entities by default.

This is about a ROM::Repository::RelationProxy don’t returning an entity with #last by ROM design.

Now the “fix” for this is documenting the use case in the description of this PR: fetch the most recent post (as instance of Post).