我觉得我在某处读到了一个动态生成模型上许多类似实例方法的ActiveRecord宏,但现在(尽管通过在线文档和RoR书籍查看)我找不到它。
我使用普通的Ruby解决了这个问题,但如果有更好的(更多Rails-y)方法,我想知道它。
所以,我有Character
,Gear
和Modifiers
模型(是的,这是RPG的应用)。角色将拥有Gear,为他的统计数据添加修饰符。所以我想要一个方法来查询他的装备(和他的装备的修改器)的每个属性,并总结相关统计数据的修饰符。 (参见下面代码中的方法)。
所以我的角色模型如下所示:
class Character < ActiveRecord::Base
has_many :gears
has_many :modifiers, :as => :modifiable, :through => :gears
stats = ["hp", "bab", "ac"] # etc...
stats.each do |method_name|
define_method method_name do
self.modifiers.where(:kind => method_name).sum(:amount)
end
end
end
所以,这样我可以做到
> jim = Character.create(:name => "Jim")
然后给吉姆一些修改他的“hp”,“bab”或“ac”的装备然后我就可以这样做:
> jim.hp
或
> jim.ac
等...
答案 0 :(得分:2)
这不是更多(Rails-y)方式,但它是代码的替代方案。方法缺失。
rubylearning.com对此有何评论。
当您向对象发送消息时,该对象将执行它在方法查找路径中找到的第一个方法,该方法的名称与消息的名称相同。如果找不到任何此类方法,则会引发NoMethodError异常 - 除非您为该对象提供了一个名为method_missing的方法...
def method_missing(m, *args, &block)
self.modifiers.where(:kind => method_name).sum(:amount)
end
关于这种方法的优点是你不需要维护你的stats数组并通过它们循环来为每个stat定义一个方法。缺点是如果每次有一个用户的missing_method它就会执行此代码,这可能是危险的。
答案 1 :(得分:0)
你可能正在考虑ActiveRecord::Base.store
,它出现在Rails 3.2中。有了它,你可以这样做:
class Character < ActiveRecord::Base
store :stats, accessors: [:hp, :bab, :ac]
end
jim = Character.create(:name => "Jim")
jim.hp = 100
注意:stats
列应定义为text
列,以确保您有足够的空间容纳您的值。