在模型的'新'之前进行回调?

时间:2014-01-26 04:50:23

标签: ruby-on-rails activerecord ruby-on-rails-4 rails-models

我有一个模型base_table,我有一个extended_table,它有额外的属性来进一步扩展我的base_table。 (我会有不同的extended_tables,为我的base_table添加不同的属性,但这与我在这里问的问题无关。)

我的base_table的模型定义如下:

class BaseTable < ActiveRecord::Base
  module BaseTableInclude
    def self.included(base)
      base.belongs_to :base_table, autosave:true, dependent: :destroy
      # do something more when this module is included
    end
  end
end

我的extended_table的模型定义如下:

class TennisQuestionaire < ActiveRecord::Base
  include BaseTable::BaseTableInclude
end

现在我想要的是下面的代码:

params = {base_table: {name:"Songyy",age:19},tennis_ball_num:3}
t = TennisQuestionaire.new(params)

当我创建t时,我也希望实例化base_table。

我可以提出的一个解决方法是解析params以创建base_table对象,然后在params上调用TennisQuestionaire.new。这就像在这里使用“before_new”过滤器一样。但是当我阅读文档时,我找不到这种过滤器。

此外,我认为另一种方法是覆盖'新'方法。但这不是那么干净。

注意:有一种名为accepts_nested_attributes_for的方法,似乎可以按我的意愿行事,但它不适用于belongs_to关系。

任何建议将不胜感激。谢谢:))

1 个答案:

答案 0 :(得分:0)

在一些路径和错误之后,解决方案是这样的:

class BaseTable < ActiveRecord::Base
  module BaseTableInclude
    def initialize(*args,&block)
      handle_res = handle_param_args(args) { |params| params[:base_table] = BaseTable.new(params[:base_table]) }
      super(*args,&block)
    end

    private
    def handle_param_args(args)
      return unless block_given?

      if args.length > 0
        params = args[0]
        if (params.is_a? Hash) and params[:base_table].is_a? Hash
          yield params
        end
      end
    end
  end
end