0

我觉得我在某处读到了关于在模型上动态生成许多类似实例方法的 ActiveRecord 宏,但现在(尽管浏览了在线文档和 RoR 书籍)我找不到它。

我已经使用普通的旧 Ruby 解决了这个问题,但是如果有更好的(更多 Rails-y)方法来解决这个问题,我想知道它。

所以,我有Character,GearModifiers模型(是的,这是一个用于 RPG 的应用程序)。角色将拥有可以为他的统计数据添加修饰符的装备。所以我想要一个方法来查询他的装备(和他的装备的修饰符)并为相关统计数据的修饰符求和。(参见下面代码中的方法)。

所以我的角色模型看起来像这样:

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

ETC...

4

2 回答 2

2

This is not a more (Rails-y) way but it is an alternative to your code. With method missing.

Where is what rubylearning.com has to say about it.

When you send a message to an object, the object executes the first method it finds on its method lookup path with the same name as the message. If it fails to find any such method, it raises a NoMethodError exception - unless you have provided the object with a method called method_missing...

def method_missing(m, *args, &block)  
  self.modifiers.where(:kind => method_name).sum(:amount)    
end

The Pros about this approach is that you don't need to be maintaining your stats array and looping thru them to define a method for each stat. The cons is that it can be dangerous if every time that there is a missing_method for a User it goes and execute this code.

于 2012-05-16T19:23:53.323 回答
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列,以确保您有足够的空间容纳您的值。

在 Rails 文档中阅读更多内容

于 2012-05-16T13:40:21.573 回答