Unclear From Documentation How To Properly Access ROM in Rails/RSpec
ylg opened this issue · 7 comments
The documentation shows ROM.env
as the way to access things from Rails' CLI, e.g., ROM.env.relations(:users)`. If used in specs, this seems to set things up a little differently than the subsequent documentation demonstrates. For example, with:
class UsersRelation < ROM::Relation[:sql]
def by_username(search_username)
[etc]
Running a spec containing something like this will work:
ROM.env.relation(:users).count
But this will not:
ROM.env.relation(:users).by_username('testuser')
Failure/Error: ROM.env.relation(:users).by_username('testuser')
NoMethodError:
undefined method `by_username' for #<#<Class:0x007fe701c8f240>:0x007fe6fe26e930>
If ROM.env is returning the same thing that the documentation just refers to as the local variable "rom" later on, then something is missing.
Similarly, trying to wrap all that in a Repository (unclear if those are deprecated) nets a similar result:
class UserRepository < ROM::Repository::Base
relations :users
def by_username(username)
users.by_username(username)
[etc]
UserRepository.new(ROM.env).by_username('testuser')
Failure/Error: found = UserRepository.new(ROM.env).by_username('testuser')
NoMethodError:
undefined method `by_username' for #<ROM::Repository::LoadingProxy:0x007fd95ad44870>
After showing the ROM.env
example for use in the CLI, the documentation just shows rom
as in rom.relation()
. I couldn't find where that rom
might be defined (and therefore how.)
After looking at this again: it seems more likely there is a step missing, or that I am missing, required to get ROM / Rails to load relations classes.
For example, even if I delete the UsersRelation's file entirely, ROM.env.relations(:users).count
and ROM.env.command(:users).create.call
still work—presumably ROM is coming up with the relations by scanning the DB rather than by looking at the relations classes, which raising the question: how does one get relations class in the mix, i.e., so that methods defined in UsersRelations are available?
Yes, you're getting the initial / pre-seeded relation from the database.
I suspect it's possible you're not loading Rails in the spec? Does the spec pass when you run everything, and only fail in isolation?
They fail in both approaches. The specs require 'rails_helper'; I don't see any other wiring steps in the docs or the tasks project (unfortunately for me the specs in that one are empty.) If it were an across the board loading failure, one would expect ROM.env.command(:users) to fail, no?
Thanks. To be clear (or less unclear), what I was attempting to point out was that I can't really tell if I'm "doing it right" by calling "rom" everywhere in Rails and "ROM.env" in Rspec, and therefore when I have problems, like the commands working but the relations not, I'm left scratching my head as to whether I've just made a dumb typo somewhere or if everything I've done is based on a wrong assumption...
Using ROM.env
is not encouraged, it's only there because Rails needs global access. You should expose rom components through your own interface. ie I have a persistence singleton object that exposes access to various rom components, it's available in specs through a helper so I can do things like persistence.users.by_name('Jane')
. In general I use a container with dependencies in my apps, so I have access to various things through a simple interface like Something.app['repositories.posts']
and provide helpers for those in tests to make it more concise.
If you don't see your methods in relations in tests then I'm 100% sure your relation classes were not loaded, thus they were not registered and so ROM inferred them from db schema. If you are using rails things should just work™. What's your rails version?
Bug cleanups; closing due to inactivity