-
-
Notifications
You must be signed in to change notification settings - Fork 166
Open
Labels
Description
Context
When defining a belongs_to association with an as: option, the struct class returned by the association method is determined by the as: value rather than the target relation's struct class.
Current Behavior
class AuthAccessGrants < DB::Relation
schema :auth_access_grants, infer: true do
associations do
belongs_to :oauth_client, foreign_key: :client_id, as: :client
end
end
end
class AuthClient < DB::Struct
def active?
active == true
end
endExpected: oauth_access_grant.client returns an AuthClient struct
Actual: oauth_access_grant.client returns a Client struct
This results in:
oauth_access_grant.client.active? #=> NoMethodErrorCurrent Workaround
The only way to access custom methods defined on AuthClient is to create an empty wrapper class:
class Client < AuthClient
endDiscussion
The as: option behaves consistently with other ROM features (e.g., posts.as(:article).to_a returns Article structs), so this is technically expected behavior. However, when used in associations, this creates a surprising experience where:
- The association name (
client) doesn't match the actual target (oauth_client) - The returned struct class (
Client) doesn't match either the association name or the target relation's struct class - Custom methods defined on the expected struct class are not available
Potential Solutions
- Add a separate option (e.g.,
as:for the method name,struct:for the struct class) - Allow
as:to accept both a symbol and a hash (e.g.,as: { method: :client, struct: :oauth_client }) - Document this behavior more clearly as a caveat of using
as:in associations