ruby-on-rails – Rails:宏风格功能

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Rails:宏风格功能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在模型和控制器中,我们经常在类定义的顶部使用像before_validation,skip_before_filter这样的Rails宏.

这是如何实现的?如何添加自定义的?

谢谢!

解决方法

它们只是标准的 Ruby函数. Ruby的灵活的语法方法使其看起来更好.您可以通过将方法编写为正常的Ruby函数,并执行以下操作之一来创建自己:

把它放在你的控制器可以访问的地方,如application.rb
将它放在一个文件中并要求它.
通过Ruby include关键字将代码混合到类中.

最后一个选项对于模型类是非常好的,第一个选项实际上只适用于控制器.

一个例子

第一种方法的一个例子如下所示.在这个例子中,我们将代码添加到ApplicationController类(在application.rb中),并在其他控制器中使用它.

class BusinessEntitiesController < ApplicationController

    nested_within :Glossary

    private

        #  Standard controller code here ....

nested_within提供帮助函数和变量来帮助识别“父”资源的id.实际上,它可以快速解析URL,并且可以由我们的每个控制器访问.例如,当一个请求进入控制器时,它被自动解析,并且类属性@parent_resource被设置为Rails find的结果.副作用是如果父资源不存在,则发回“未找到”响应.这样可以节省我们在每个嵌套资源中输入锅炉代码.

这听起来很聪明,但它只是一个标准的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

nested_within函数在ApplicationController(controllers / application.rb)中定义,因此被自动拉入.

请注意,nested_within在控制器类的主体内执行.这将方法find_parent_id添加到控制器.

概要

Ruby的灵活语法和Rail的惯例配置的组合使得它看起来比实际上更强大(或更强).

下一次你找到一个很酷的方法,只需在它的前面放一个断点并追踪它.啊开源!

让我知道,如果我可以进一步帮助,或者如果你想要一些指针,如何嵌套代码的工作原理.

克里斯

猜你在找的Ruby相关文章