如何制作范围,将输出自定义数据?
How to make scope, that will output custom data?
我有模型 Category
和 Transactions
。
Category has_many transactions
, Transaction belongs_to category
.
而且我有 Category
的空间:
@relation = Category.all
@relation.joins(:transactions).where('transactions.created_at >= ?', 1.month.ago).
group('categories.id').order('SUM(transactions.debit_amount_cents) DESC')
它显示类别并按 transactions.debit_amount_cents
的总和对它们进行排序
我想显示其所有交易的金额以及每个类别。
喜欢:
id: 1,
name: "Category1",
all_amount: *some value* #like this
如何改进这个范围?
class Category < ApplicationRecord
# remember that scope is just a widely abused syntactic sugar
# for writing class methods
def self.with_recent_transactions
joins(:transactions)
.where('transactions.created_at >= ?', 1.month.ago)
.select(
'categories.*',
'SUM(transactions.debit_amount_cents) AS total_amount'
)
.order('total_amount DESC')
.group('categories.id')
end
end
如果您 select 列或聚合并为其指定别名,它将在生成的模型实例中可用。
Category.with_recent_transactions.each do |category|
puts "#{category.name}: #{category.total_amount}"
end
为了便携性,您可以使用 Arel 而不是 SQL 字符串来编写它,这样可以避免像 table 名称这样的硬编码内容:
class Category < ApplicationRecord
def self.with_recent_transactions
t = Transaction.arel_table
joins(:transactions)
.where(transactions: { created_at: Float::Infinity..1.month.ago })
.select(
arel_table[Arel.star]
t[:debit_amount_cents].sum.as('total_amount')
)
.order(total_amount: :desc) # use .order(t[:debit_amount_cents].sum) on Oracle
.group(:id) # categories.id on most adapters except TinyTDS
end
end
在 Rails 6.1 (backported to 6.0x) 中,您可以使用无开始范围来创建没有 Float::Infinity
的 GTE 条件:
.where(transactions: { created_at: ..1.month.ago })
我有模型 Category
和 Transactions
。
Category has_many transactions
, Transaction belongs_to category
.
而且我有 Category
的空间:
@relation = Category.all
@relation.joins(:transactions).where('transactions.created_at >= ?', 1.month.ago).
group('categories.id').order('SUM(transactions.debit_amount_cents) DESC')
它显示类别并按 transactions.debit_amount_cents
我想显示其所有交易的金额以及每个类别。
喜欢:
id: 1,
name: "Category1",
all_amount: *some value* #like this
如何改进这个范围?
class Category < ApplicationRecord
# remember that scope is just a widely abused syntactic sugar
# for writing class methods
def self.with_recent_transactions
joins(:transactions)
.where('transactions.created_at >= ?', 1.month.ago)
.select(
'categories.*',
'SUM(transactions.debit_amount_cents) AS total_amount'
)
.order('total_amount DESC')
.group('categories.id')
end
end
如果您 select 列或聚合并为其指定别名,它将在生成的模型实例中可用。
Category.with_recent_transactions.each do |category|
puts "#{category.name}: #{category.total_amount}"
end
为了便携性,您可以使用 Arel 而不是 SQL 字符串来编写它,这样可以避免像 table 名称这样的硬编码内容:
class Category < ApplicationRecord
def self.with_recent_transactions
t = Transaction.arel_table
joins(:transactions)
.where(transactions: { created_at: Float::Infinity..1.month.ago })
.select(
arel_table[Arel.star]
t[:debit_amount_cents].sum.as('total_amount')
)
.order(total_amount: :desc) # use .order(t[:debit_amount_cents].sum) on Oracle
.group(:id) # categories.id on most adapters except TinyTDS
end
end
在 Rails 6.1 (backported to 6.0x) 中,您可以使用无开始范围来创建没有 Float::Infinity
的 GTE 条件:
.where(transactions: { created_at: ..1.month.ago })