2

I have Hanami models User and UserInfo that have has_one association.

Repositories look the following:

class UserInfoRepository < Hanami::Repository
end

class UserRepository < Hanami::Repository
  associations do
    has_one :user_info
  end
end

Question: who can I join and load both tables with one query? (I am looking for something similar to Rails' includes).

So far I've tried

def users_with_info
  users.join(:user_info)
end

It does the join, but does not select columns from user_infos table.

Thanks in advance.

Sergey Potapov
  • 3,819
  • 3
  • 27
  • 46
  • I'm not familiar with Hanami but it looks like it uses `rom-repository` and `sequel` under the scenes. Something like `aggregate(:user_info)` should work according to http://api.rom-rb.org/rom/ROM/Repository/Root#aggregate-instance_method let me know if this helps so i can make it the answer – Leo Correa Apr 24 '18 at 21:54
  • Thanks. `aggregate` is quite similar to what I am trying to achieve: it returns the same set of data I am trying to obtain, but it does 2 request: - first to fetch all `users` - second to fetch all `user_infos` with condition `user_id IN (1,2,3,4, 5 ...)`. It just enumerates ids of all fetched users in SQL query. – Sergey Potapov Apr 24 '18 at 22:07
  • I wonder if performing the join and then the aggregate explicitly would work. I'm sorry I don't have much knowledge of the gems. Just vaguely looked at the docs – Leo Correa Apr 24 '18 at 23:44

2 Answers2

2

When you fetch data via a Repository in Hanami the result set is mapped into entities. By default the UserRepository will map to the User entity. I'm guessing that that entity does not have attributes for the columns from user_info.

What you need to do is create an Entity that can contain the data that you want to fetch from the database and then call .as(ThatEntityYouCreated) on the result set. E.g.,

def users_with_info
  users.join(:user_info).map_to(UserWithInfo)
end

If you do not want to create an Entity and just want to get a plain hash, you can do this:

users.join(:user_info).map.to_a

However, I consider this to be a crutch. You should not return Hashes from your Repository methods.

kaikuchn
  • 795
  • 7
  • 15
1

I believe we faced this exact issue with a teammate of mine on one of our Hanami project, and this is how we solved it.

We basically bypassed Hanami repository, going straight to the underlying ROM relation, using ROM::Relation#wrap in order to get our User entity joined with the entity of interest.

Let met know if it helped you, or if you need more details. Cheers!

nfilzi
  • 62
  • 1
  • 7