Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用钩子运行的关注点方法与使用模型运行的关注点方法的性能差异?_Mysql_Ruby On Rails - Fatal编程技术网

Mysql 使用钩子运行的关注点方法与使用模型运行的关注点方法的性能差异?

Mysql 使用钩子运行的关注点方法与使用模型运行的关注点方法的性能差异?,mysql,ruby-on-rails,Mysql,Ruby On Rails,基本上,我注意到在初始化钩子之后,在钩子中动态重写ActiveRecord::Base模型的getter和在模型本身中动态重写getter有很大的性能差异 假设我有以下顾虑: module Greeter extend ActiveSupport::Concern included do after_initialize { override_get_greeting } end def override_get_greeting self.class::CO

基本上,我注意到在初始化钩子之后,在
钩子中动态重写
ActiveRecord::Base
模型的getter和在模型本身中动态重写getter有很大的性能差异

假设我有以下顾虑:

module Greeter
  extend ActiveSupport::Concern

  included do
    after_initialize { override_get_greeting }
  end

  def override_get_greeting
    self.class::COLS.each do |attr|
      self.class.class_eval do
        define_method attr do
          "Hello #{self[attr]}!"
        end
      end
    end
  end

end
然后,我有以下模型,由一个带有名称的表组成。

CREATE TABLE 'names' ( 'name' varchar(10) );
INSERT INTO names (name) VALUES ("John")
这个很好用。然而,如果我试着用一种更为Rails的方式来做这件事,它会明显地慢一些

本质上,我只想将一个参数传递到包含
COLS
Greeter
方法中,然后覆盖getter。它看起来像:

# Greeter
module Greeter
  extend ActiveSupport::Concern

  def override_get_greeting(cols)
    cols.each do |attr|
      self.class.class_eval do
        define_method attr do
          "Hello #{self[attr]}!"
        end
      end
    end
  end

end

# Name
class Name < ActiveRecord::Base
  include Greeter
  override_get_greeting [:name]
end
#迎宾员
模块迎宾员
扩展ActiveSupport::关注点
def覆盖获取问候语(cols)
每种颜色都有颜色|
self.class.class\u eval do
定义方法attr do
“你好{self[attr]}!”
终止
终止
终止
终止
终止
#名字
类名
现在
Name.where(Name:'John')。first.Name#你好,John在第一次呼叫时大约慢2秒

我的手指插不进去。我假设从第一个示例开始,应用程序的运行速度要慢一些,但不是很确定

我更喜欢第二个例子,但是性能上的差异是很大的


有人遇到过类似的情况吗?

除非真正的应用程序代码与上面显示的完全不同,否则这不可能造成2秒的性能损失

然而,编写代码仍然是一种不必要的冗长和低效的方式:每次初始化类时,都要在类实例上重新定义方法

您可以只定义一次方法,而不是在初始化后使用
。例如,您可以将其放入
迎宾
模块:

included do |klass|
  klass::COLS.each do |attr|
    define_method attr do                                  
      "Hello #{self[attr]}!"                               
    end
  end
end

另外值得注意的是,您可能希望使用
super()
,而不是
self[attr]
。行为将是相同的(假设不存在其他覆盖),但如果列不存在,则会引发错误。

尝试使用
VARCHAR(255)
作为默认值,并且仅当您有非常令人信服的理由时才限制此操作。对于许多事情,如姓名和电子邮件地址,较短的字段可能会给用户带来巨大的麻烦。感谢
super()
提示。您是否建议继续使用常量?我更希望有一个调用的方法能够触发getter重写。这不会对性能造成影响,但是如果您愿意,可以使用一个方法。
# Greeter
module Greeter
  extend ActiveSupport::Concern

  def override_get_greeting(cols)
    cols.each do |attr|
      self.class.class_eval do
        define_method attr do
          "Hello #{self[attr]}!"
        end
      end
    end
  end

end

# Name
class Name < ActiveRecord::Base
  include Greeter
  override_get_greeting [:name]
end
included do |klass|
  klass::COLS.each do |attr|
    define_method attr do                                  
      "Hello #{self[attr]}!"                               
    end
  end
end