我对元编程比较陌生,我试图在单个表继承下定义子模型中的getter和setter,如下所示:
# app/models/player.rb
class Player < ActiveRecord::Base
serialize :equipments
protected
# Define getters for setters for individual sports
def attr_equipments(*attributes)
attributes.each do |attribute|
define_singleton_method(attribute) do
self.equipments[attribute.to_sym]
end
define_singleton_method("#{attribute}=") do |value|
self.equipments[attribute.to_sym] = value
end
end
end
end
# app/models/baseball_player.rb
class BaseballPlayer < Player
after_initialize do
attr_equipments :bat, :glove
end
end
在更高层,我想做这样的事情:
# app/controllers/baseball_players_controller.rb
class BaseballPlayersController < ApplicationController
def new
@baseball_player = BaseballPlayer
end
end
# app/views/baseball_players/new.html.haml
=form_for(@baseball_player) do |f|
=f.text_field :bat
=f.text_field :glove
=f.submit
但是通过上面的示例,即使从控制台也无法获取或设置属性。
> p = BaseballPlayer.new
> p.bat
> # returns NoMethodError: undefined method `[]' for nil:NilClass
> p = BaseballPlayer.new
> p.bat = "Awesome bat"
> # returns ArgumentError: wrong number of arguments (0 for 2..3)
有人能帮我找到合适的方向吗?非常感谢提前。
答案 0 :(得分:0)
我自己刚刚解决了这个问题..
对于将来的引用,此部分需要存储,因为序列化不会自动定义任何访问器。
# app/models/player.rb
class Player < ActiveRecord::Base
# serialize :equipments -> does not create a setter or getter needed
store :equipments
我在控制器中的create方法中也遇到错误:
def create
@alarm = BaseballPlayer.new(alarm_params)
# Error: undefined attribute 'bat'
解决了:
def create
@alarm = BaseballPlayer.new
@alarm.assign_attributes(alarm_params)