Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.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
Ruby on rails 在类主体中声明的Ruby方法调用_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 在类主体中声明的Ruby方法调用

Ruby on rails 在类主体中声明的Ruby方法调用,ruby-on-rails,ruby,Ruby On Rails,Ruby,我刚刚开始学习ruby on rails,遇到了如下代码: class Post < ActiveRecord::Base validates_presence_of :title belongs_to :user end class Post

我刚刚开始学习ruby on rails,遇到了如下代码:

class Post < ActiveRecord::Base
 validates_presence_of   :title
 belongs_to :user
end
class Post
类主体内有两个方法调用。 我很难找到任何 描述从类体内部(但在任何方法外部)进行的方法调用是如何工作的。 我所有的书都只描述了如何定义类和实例方法以及如何 从其他方法中调用它们

class Klass
  extend(Module.new do
    def add_getter_and_setter(symbol)
      ..
    end
  end)
end
我的问题是: 如何以及何时调用这些方法?
它们是如何定义的?它们是在某个活动记录模块中定义的混合吗?

您看到的是用于活动记录对象的类级方法。要编写自己的方法,使其执行类似的操作,可以将其作为插件编写,然后通过重新打开类定义将其包含到ActiveRecord中。创建插件的Ruby on Rails指南:

介绍如何编写这样的插件/类级方法。这是一个很好的文档,介绍了如何理解这些方法的含义以及它们如何与实例交互

Re: How and when are these methods called?
当类被加载时调用它们。您可以在其中一个方法中放置一个断点,并查看它是否作为rails项目启动的一部分被调用

How are they defined?
它们是类方法。因为这是ruby,所以可以用多种方式定义它们

Are they mixins defined in some active record module?
在这种情况下,
验证的存在在
供应商/rails/activerecord/lib/active\u记录/validations中定义。rb
属于
vendor/rails/activerecord/lib/active\u record/associations.rb
ActiveRecord
是一个大型系统,包括许多混音器、模块等


请注意,要查看方法的定义位置,我使用每个方法,请参阅定义底部的“Show Source”链接。

类定义的主体是代码的执行上下文,与其他任何方法一样。代码在类的上下文中执行(意思是self是类对象,它是类的实例)。可以有局部变量和实例变量(属于类对象本身而不是类的实例),并且可以调用类对象响应的任何方法。一旦类定义块完成,代码就会运行


在本例中,ActiveRecord::Base定义类方法
验证
属于

Yehuda Katz在他的博客上对此有很好的解释。参见第4点:。

这些是类方法或“单例”方法。您应该熟悉的是attr_访问器。我们可以在测试类中实现类似的东西

class Klass
  def self.add_getter_and_setter(symbol)
    module_eval "def #{symbol}; @#{symbol}; end"
    module_eval "def #{symbol}=(val); @#{symbol} = val; end"
  end
end

class Person < Klass
  add_getter_and_setter :name
  add_getter_and_setter :phone
end

person = Person.new
person.name = 'John Smith'
person.phone = '555-2344'
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344">
如果已经定义了Klass,我们可以重新打开它来添加类方法

class Klass
end

def Klass.add_getter_and_setter(symbol)
  ..
end

# or 

class << Klass
  def add_getter_and_setter(symbol)
    ..
  end
end
class Klass
end

def Klass.add_getter_and_setter(symbol)
  ..
end

# or 

class << Klass
  def add_getter_and_setter(symbol)
    ..
  end
end
person = Person.find(1) # finds a person with id:1