我在config / application.rb中添加了一个变量:
config.available_account_types = %w(SystemAccount CashAccount DemandAccount LiabilityAccount CreditCardAccount)
并在模型account.rb中生成了一些范围:
for t in Mypurse::Application.config.available_account_types
scope t.underscore.pluralize.to_sym, -> {where(type: t)}
end
但是当我尝试所有这些,Account.system_accounts,Account.cash_accounts等时,我为每种帐户类型都获得了这个sql:
where type = 'CreditCardAccount'
也就是说,所有生成的范围都指向{where(type: 'CreditCardACcount')}
我不知道为什么。
这是源文件: https://github.com/chylli/mypurse/blob/add_cash_demand_liability_credit_card/config/application.rb
https://github.com/chylli/mypurse/blob/add_cash_demand_liability_credit_card/app/models/account.rb
答案 0 :(得分:1)
我认为这是因为范围被赋予Proc
只会在被调用时执行,因此t
将始终是循环的最后一个元素。
解决方案是定义方法而不是范围(完全相同):
MyPurs::Application.config.available_account_types.each do |account_type|
define_singleton_method(account_type.underscore.pluralize.to_sym) do
where(type: "#{account_type}")
end
end
但由于这不会声明proc,因此应该按预期工作。
此外for .. in
很少用于红宝石,我个人更喜欢使用更惯用的.each
(但当然你可以自由使用你想要的任何东西,程序员的幸福是红宝石的关键:) :) / p>
现在除此之外,虽然元编程真的很酷,但你应该问自己是否只是列出范围更具可读性。我理解:元编程更干,但就个人而言,在我这样做的大多数情况下,由于可读性,我恢复了明确的定义。
答案 1 :(得分:0)
我不确定您为何定义了' config.available_account_types',因为这是业务逻辑。这应该属于Account
模态。所以我会做这样的事情
class Account < ActiveRecord::Base
ACCOUNT_TYPES = %w(SystemAccount CashAccount DemandAccount LiabilityAccount CreditCardAccount)
ACCOUNT_TYPES.each do |acccount_type|
define_singleton_method(account_type.underscore.pluralize.to_sym) do
where(type: "#{account_type}")
end
end
end