Ruby on rails 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的类级别定义
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!"