ruby-on-rails – Rails方法如何调用“has_one”?
我是
PHP开发人员,目前我正在学习Rails(3),当然还有Ruby.
I don’t want to believe in magic所以我尽可能地了解Rails背后发生的事情.我发现有趣的是ActiveRecord模型中的方法调用,如has_one或belongs_to.
我试图重现这一点,并带来了天真的例子: # has_one_test_1.rb module Foo class Base def self.has_one puts 'Will it work?' end end end class Model2 < Foo::Base has_one end 只是运行这个文件将输出“它会工作吗?”,正如我所料. 在搜索rails源代码时,我找到了负责的功能:def has_one(association_id,options = {}). 这怎么可能,因为它显然是一个实例(?)而不是一个类方法,它应该不起作用. 经过一番研究,我找到了一个可以回答的例子: # has_one_test_2.rb module Foo module Bar module Baz def has_one stuff puts "I CAN HAS #{stuff}?" end end def self.included mod mod.extend(Baz) end end class Base include Bar end end class Model < Foo::Base has_one 'CHEEZBURGER' end 现在运行has_one_test_2.rb文件将输出I CAN HAS CHEEZBURGER.如果我理解这一点 – 首先发生的事情是Base类试图包含Bar模块.在包含时,调用self.included方法,它使用Baz模块(及其实例has_one方法)扩展Bar模块.所以本质上has_one方法被包含(混合?)到Base类中.但是,我仍然没有完全理解它. Object#extend从模块添加方法但仍然,我不知道如何使用extend重现此行为.所以我的问题是: >这里究竟发生了什么.我的意思是,还是不知道has_one方法怎么变成类方法?究竟是哪一部分造成的? 解决方法
您可以扩展并包含一个模块.
extend将模块中的方法添加为类方法 module Bar def has_one stuff puts "I CAN HAS #{stuff}?" end end class Model extend Bar has_one 'CHEEZBURGER' end include将模块中的方法添加为实例方法 class Model include Bar end Model.new.has_one 'CHEEZBURGER' Rails使用它来动态地向您的类添加方法. 例如,您可以使用define_method: module Bar def has_one stuff define_method(stuff) do puts "I CAN HAS #{stuff}?" end end end class Model extend Bar has_one 'CHEEZBURGER' end Model.new.CHEEZBURGER # => I CAN HAS CHEEZBURGER? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |