【问题标题】:Creating dynamic instance methods in after_save callback rails在 after_save 回调 rails 中创建动态实例方法
【发布时间】:2016-06-04 07:15:30
【问题描述】:

我在名为 Field 的模型中有一个 after_save 回调,并且我正在其他名为 User 的模型中创建动态实例方法,但代码不起作用,我无法弄清楚有什么问题它,因为逻辑很简单。请帮助。

class field < ActiveRecord::Base

  after_create :create_user_methods

  private

    def create_user_methods
      User.class_eval do
        define_method(self.name) do
          #some code
        end

        define_method(self.name + "=") do
          #some code
        end
      end
    end

end

然后我像这样在rails console 中创建 Field 实例

  Field.create(name: "test_method")

然后像这样在 User 类实例上调用该方法

  User.new.test_method

但它会引发错误

未定义的方法test_method for ....

【问题讨论】:

  • 定义的方法将只在应用程序的同一实例中可用。这意味着在带有 puma 或 unicorn 服务器的默认生产系统上,有多个工作人员,甚至可能有多个服务器,这将失败。您能否解释一下,您为什么要这样做以及您要达到的目标是什么?
  • @spickermann 很简单,我想根据 Field 对象名称在 User 类对象上创建方法。
  • @spickermann,感谢您的评论,我以前没有意识到这一点。在这样的系统中,最好在 User 模型中使用 method_missing 来获取所有当前定义的字段(尽管我猜性能会受到影响)。
  • 当然,我明白这一点。但为什么?你认为你为什么需要它?
  • @spickermann 作为最终用户可以在运行时创建新的Field 对象并且我不想重新启动服务器,我在User 模型中定义了一个循环,它创建了与每个​​对象对应的方法现有Field 对象在服务器启动时以相同的方式,但正如@Borama 建议的那样,我可以在这里使用method_missing。

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


【解决方案1】:

我得到了修复,我不能在 class_eval 块内使用 self,因为它的值是用户模型而不是 Field 类对象,因此修复是:

class field < ActiveRecord::Base

  after_create :create_user_methods

  private

    def create_user_methods

      name = self.name # here self points to field object

      User.class_eval do
        define_method(name) do
          #some code
        end

        define_method(name + "=") do
          #some code
        end
      end
    end
  end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多