在模型和控制器,我们经常使用Rails的宏一样before_validation
,skip_before_filter
在类定义的顶部.
这是如何实现的?如何添加自定义的?
谢谢!
Chr*_*ley 20
它们只是标准的Ruby函数.Ruby灵活的语法方法使它看起来比它更好.您可以通过将方法编写为普通的Ruby函数并执行以下操作之一来创建自己的:
把它放在你的控制器可以访问的地方,比如application.rb
把它放在一个文件中并要求它.
通过Ruby include
关键字将代码混合到一个类中.
最后一个选项对于模型类很有用,第一个选项实际上只适用于控制器.
第一种方法的一个例子如下所示.在这个例子中,我们将代码添加到ApplicationController类(在application.rb中)并在其他控制器中使用它.
class BusinessEntitiesController < ApplicationController
nested_within :Glossary
private
# Standard controller code here ....
Run Code Online (Sandbox Code Playgroud)
该nested_within提供帮助函数和变量,以帮助识别"父"资源的ID.实际上它会动态解析URL,并且每个控制器都可以访问它.例如,当一个请求进入控制器时,它会被自动解析,并且类属性@parent_resource被设置为Rails查找的结果.副作用是如果父资源不存在则发回"未找到"响应.这使我们无需在每个嵌套资源中键入样板代码.
这听起来很聪明,但它只是一个标准的Ruby功能......
def self.nested_within(resource)
#
# Add a filter to the about-to-be-created method find_parent_ud
#
before_filter :find_parent_id
#
# Work out what the names of things
#
resource_name = "#{resource.to_s.tableize.singularize}"
resource_id = "#{resource_name}_id"
resource_path = "#{resource.to_s.tableize}_path"
#
# Get a reference to the find method in the model layer
#
finder = instance_eval("#{resource}.method :find_#{resource_name}")
#
# Create a new method which gets executed by the before_filter above
#
define_method(:find_parent_id) do
@parent_resource = finder.call(params[resource_id])
head :status => :not_found, :location => resource_path
unless @parent_resource
end
end
Run Code Online (Sandbox Code Playgroud)
nested_within函数在ApplicationController(controllers/application.rb)中定义,因此会自动引入.
请注意,nested_within在控制器类的主体内执行.这将方法find_parent_id添加到控制器.
结合使用Ruby的灵活语法和Rail的约定配置使得这一切看起来比实际更强大(或更加笨拙).
下次找到一个很酷的方法时,只需在它前面粘一个断点并跟踪它.啊开源!
让我知道我是否可以进一步提供帮助,或者如果你想了解嵌套代码如何工作的一些指示.
克里斯
Ian*_*ell 16
克里斯的回答是正确的.但是这里是你想要编写自己的代码的地方:
添加类似Controller方法的最简单方法是在以下位置定义它ApplicationController
:
class ApplicationController < ActionController::Base
...
def self.acts_as_awesome
do_awesome_things
end
end
Run Code Online (Sandbox Code Playgroud)
然后您可以从各个控制器访问它,如下所示:
class AwesomeController < ApplicationController
acts_as_awesome
end
Run Code Online (Sandbox Code Playgroud)
对于模型,您想要重新打开ActiveRecord::Base
:
module ActiveRecord
class Base
def self.acts_as_super_awesome
do_more_awesome_stuff
end
end
end
Run Code Online (Sandbox Code Playgroud)
我个人会把它放在一个文件中,config/initializers
以便它被加载一次,所以我知道在哪里寻找它总是.
然后你可以在这样的模型中访问它:
class MySuperAwesomeModel < ActiveRecord::Base
acts_as_super_awesome
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5499 次 |
最近记录: |