New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't chain other operators or #as, etc from addition or subtraction #89
Comments
This seems... important? But there are no responses to this issue, so maybe I'm just missing something (I'm fairly new to ARel). Given: t = Users.arel_table
Users.select(t[:name]).select(t[:post_count] + t[:comment_count]) ... can I access the (post_count + comment_count) here without an alias? Am I just using this "wrong"? |
Ah, it seems I can do this:
|
This may have been fixed by c78227d though I am unsure. |
@parndt Nope, it doesn't work, not even in |
Same problem 😞 I'm need to get subtraction of 3 columns as quantity: (items[:quantity] - items[:available_quantity] - items[:to_back_order]).as("quantity") and I'm get this error: NoMethodError: undefined method `-' for #<Arel::Nodes::Grouping:0x007fb9332a3ed0> because first substraction operation returns |
Workaround for my case: Arel::Nodes::TableAlias.new(Arel::Nodes::Grouping.new(
Arel::Nodes::Subtraction.new(
Arel::Nodes::Subtraction.new(
items[:quantity],
items[:available_quantity]
),
items[:to_back_order]
)
), Arel::Nodes::SqlLiteral.new("AS quantity")) |
My case is similiar to @drakmail. I wanted to get: (activities.logged_at - root_ancestor.logged_at) AS duration I worked around by converting the calculation to SQL and wrapping in # activities = Activity.arel_table
# root_ancestor is an Arel::Table object
...
duration_term = (root_ancestor[:logged_at] - activities[:logged_at]).to_sql
...
@activities.arel
.project(Arel.sql(duration_term).as('duration'))
... |
Thanks, @drakmail! I extended your solution to match my case in which I have to prioritize operators: # (current_revenue - last_month_revenue) / last_month_revenue * 100
revenue_change = Arel::Nodes::Grouping.new(
Arel::Nodes::Subtraction.new(
arel_table[:current_revenue],
arel_table[:last_month_revenue]
)
)
Arel::Nodes::TableAlias.new(Arel::Nodes::Grouping.new(
Arel::Nodes::Multiplication.new(
Arel::Nodes::Division.new(
revenue_change,
arel_table[:last_month_revenue]
),
100
)
), Arel::Nodes::SqlLiteral.new('AS monthly_revenue_change')) |
Per #523, Arel development is moving to rails/rails. If this issue is still relevant, please consider reopening it over there. (Note that the Rails repository does not accept feature request issues, and requires reproduction steps that rely on Active Record's documented API.) |
An addition or subtraction results in a Nodes::Grouping instance, and that class does not have the mixins to support chaining additional methods. I can't even specify a column name using #as (e.g. (foo_table[:value] + 1).as(foo_plus_one). Attempting to do so results in...
NoMethodError: undefined method `as' for #Arel::Nodes::Grouping:0x00000102e9b968
Likewise, I can't chain an addition to an addition, etc. The same problem does not exist for multiplication and division, because those return instances of Nodes::Binary subclasses rather than Nodes::Grouping.
It seems to me that the addition and subtraction operators should return instances of something like a MathGrouping class that includes the same mixins that Nodes::Binary and Attributes::Attribute do (and maybe there should be another module that encapsulates that combination of inclusions).
The text was updated successfully, but these errors were encountered: