Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.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 Rails类如何直接在类上调用方法_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails Rails类如何直接在类上调用方法

Ruby on rails Rails类如何直接在类上调用方法,ruby-on-rails,ruby,Ruby On Rails,Ruby,我试图了解更多关于rails的神秘方式,我有以下问题 当我在一个类(例如模型)中时,我可以直接调用方法,而无需将方法调用放在模型的方法中 例如: Post < ApplicationRecord has_many :comments end 那么Rails是如何做到的呢?我一直看到它,甚至看到一些添加这些方法调用的gem,例如,acts\u as\u votable 有人能解释一下发生了什么吗?这是因为has\u many是在ApplicationRecord的类级别定义

我试图了解更多关于rails的神秘方式,我有以下问题

当我在一个类(例如模型)中时,我可以直接调用方法,而无需将方法调用放在模型的方法中

例如:

Post < ApplicationRecord
   
   has_many :comments

end
那么Rails是如何做到的呢?我一直看到它,甚至看到一些添加这些方法调用的gem,例如,
acts\u as\u votable


有人能解释一下发生了什么吗?

这是因为has\u many是在ApplicationRecord的类级别定义的。如果您将父类中的#say#u hello方法更改为类方法,它将起作用。这就是我的意思:

class父类
打个招呼
p“来自父类的你好”
结束
结束

这里有两个重要的概念-第一个是Ruby与Java等更经典的语言不同,类主体只是一块可执行代码:

class Foo
  puts "I can do whatever I want here!!!"
end
class
只需声明常量(或重新打开已存在的类),并在创建(或重新打开)的类的上下文中执行块。这个类是类的一个实例,我们称之为singleton类或eigenclass,这可能是一个令人困惑的概念,但是如果你想一想在Ruby中一切都是对象,类只是创建实例的蓝图的对象,因此可以有自己的方法和属性,那么它会有所帮助

第二个概念是内隐自我。在Ruby中,方法调用总是有一个接收者——如果不指定接收者,则假定它是
self
<类decoration块中的code>self是类本身:

class Bar
  puts name # Bar
  # is equivalent to
  puts self.name
end
因此,您可以通过简单地将方法定义为类方法而不是实例方法来修复示例:

class ParentClass
  def self.say_hello
    p "Hello from Parent Class"
  end

  say_hello # Hello from Parent Class
end 
has\u many
仅仅是从
ActiveRecord::Base
继承下来的一个类方法,它通过添加方法来修改类本身

class Thing < ApplicationRecord
  puts method(:has_many).source_location # .../activerecord-6.0.2.1/lib/active_record/associations.rb 1370
end

它并不是真正的魔法——它只是一个修改类本身的类方法。

这很有意义。一旦有人告诉你,它总是那么明显,呃:)谢谢你的朋友,非常感谢。哇,这真的很有见地,也很有帮助。谢谢你花时间解释,现在真的更有意义了。非常感谢。
class Thing < ApplicationRecord
  puts method(:has_many).source_location # .../activerecord-6.0.2.1/lib/active_record/associations.rb 1370
end
class Foo
  def self.define_magic_method(name)
    define_method(name) do
      "We made this method with magic!" 
    end
  end

  def self.define_magic_class_method(name)
    define_singleton_method(name) do
      "We made this method with magic!" 
    end
  end

  define_magic_method(:bar)
  define_magic_class_method(:bar)
end
irb(main):048:0> Foo.new.bar
=> "We made this method with magic!"
irb(main):048:0> Foo.baz
=> "We made this method with magic!"