Ability to alias an attribute but keeping type inferred

If I’m not wrong, it is not possible to create an alias for a relation attribute without having to redefine its writer type, too:

schema(:users, infer: true) do
  attribute :act, Type::Strict::Bool.meta(alias: :active)
end

In the previous example all attributes of :users relation are inferred, except for the need to rename :act to :active which forces me to redefine its type.

I think it is an unnecessary coupling. I don’t see the name given to an attribute as something related to its type. I think type information should be related just with the attribute value. It is weird, it is like saying that a variable type depends on the name you give to this variable. I think there is a smell in the fact that the reader type, even if it isn’t defined, will use the same aliased name.

It would be really useful for legacy schemas, where you want to rename attributes but still rely on the automatic inferring of types.

What do you think?

1 Like

Yeah in general I find aliasing way more cumbersome than it should be. I’m having trouble remembering the exact occurrence but I have run into a number of pain points surrounding sql_expr, AliasesExpression, and renaming attributes. Ideally it would be easier to just alias the attributes within the default dataset. Currently the only robust way I’ve found to do this is to use SQL views/materialized views.

Would it be considered a PR about it? If so, I’d love some guidance about the best way to implement it. Something like?

attribute :act, alias: :active

or

alias_attribute :act, :active

You can do this using dataset { .. } at the relation class level

The only reason why this works like that is that a proper public API for configuring attributes is just not present. At the moment, we still chuck attribute settings into their type’s meta bag, rather than keeping it separate. This means that once we start storing attributes settings separate from their type settings, we will be able to introduce an API like:

# with partial inference
schema(:users, infer: true) do
  attribute :act, as: :active
end

# without inference
schema(:users) do
  attribute :act, Types::Bool, as: :active
end 

I’d be more than happy to see a PR that does just that, we could include it in 5.0.0 or 4.x (or both, probably).

Cool. I’ll try to find the time :slight_smile:

1 Like

Meanwhile, can I ask to elaborate a bit on this? Neither of the following seems to work:

dataset { 
  Sequel.as :act, :active

  self
 }
dataset {
  Sequel::SQL::AliasedExpression.new(:act, :active)

  self
} 
dataset {
  Sequel[:users][:act].as(:active)

  self
}

You can read about this in the docs.

I actually just realized this won’t do what you want, because you still need to define aliased attributes in the schema.

Ok, I was afraid of that. This pushes me in the direction of hurrying with that PR :slight_smile:

Thanks!

1 Like