Направляющие: макро-функции стиля

У вас есть файл с именем json или simplejson на вашем пути, который не является одной из этих двух библиотек? Если вы это сделаете, то Python загрузит этот файл вместо реальной библиотеки.

13
задан Grnbeagle 29 May 2009 в 15:09
поделиться

2 ответа

Это просто стандартные функции Ruby. Благодаря гибкому подходу Ruby к синтаксису он выглядит лучше, чем есть на самом деле. Вы можете создать свой собственный, просто написав свой метод как обычную функцию Ruby и выполнив одно из следующих действий:

  1. поместив его в место, доступное для ваших контроллеров, например application.rb

  2. , поместив его в файл и потребовав его в .

  3. смешивание кода с классом с помощью ключевого слова Ruby include .


Последний вариант отлично подходит для классов моделей, а первый вариант действительно только для контроллеров.


Пример


] Пример первого подхода показан ниже. В этом примере мы добавляем код в класс ApplicationController (в application.rb) и используем его в других контроллерах.

class BusinessEntitiesController < ApplicationController

    nested_within :Glossary

    private

        #  Standard controller code here ....

nested_within предоставляет вспомогательные функции и переменные, помогающие идентифицировать идентификатор «родительского» ресурса. Фактически, он анализирует URL-адрес на лету и доступен каждому из наших контроллеров. Например, когда запрос поступает в контроллер, он автоматически анализируется, а атрибут класса @parent_resource устанавливается равным результату поиска Rails. Побочным эффектом является то, что ответ «Не найдено» отправляется обратно, если родительский ресурс не существует. Это избавляет нас от необходимости набирать стандартный код во всех вложенных ресурсах. он автоматически анализируется, и атрибут класса @parent_resource устанавливается равным результату поиска Rails. Побочным эффектом является то, что ответ «Не найдено» отправляется обратно, если родительский ресурс не существует. Это избавляет нас от необходимости набирать стандартный код во всех вложенных ресурсах. он автоматически анализируется, и атрибут класса @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


Функция nested_within определена в ApplicationController (controllers / application.rb) и поэтому втягивается автоматически.

Обратите внимание, что nested_within выполняется внутри тела класса контроллера. Это добавляет к контроллеру метод find_parent_id.


Резюме

Комбинация гибкого синтаксиса Ruby и конфигурации Rail-соглашения делает все это более мощным (или более странным), чем оно есть на самом деле.

В следующий раз, когда вы найдете классный метод, просто поставьте перед ним точку останова и проследите через нее. Ах, открытый исходный код!

Дайте мне знать, если я могу помочь, или если вам нужны некоторые указатели на то, как работает этот код nested_within.

Chris

20
ответ дан 1 December 2019 в 19:23
поделиться

Ответ Криса правильный. Но здесь вы хотите использовать свой код для написания собственного:

Самый простой способ добавить такие методы контроллера - это определить его в ApplicationController :

class ApplicationController < ActionController::Base
  ...
  def self.acts_as_awesome
    do_awesome_things
  end
end

Затем вы можете получить к нему доступ с отдельных контроллеров примерно так:

class AwesomeController < ApplicationController
  acts_as_awesome
end

Для моделей, вы хотите повторно открыть ActiveRecord :: Base :

module ActiveRecord
  class Base
    def self.acts_as_super_awesome
      do_more_awesome_stuff
    end
  end
end

Я лично поместил бы это в файл в config / initializers , чтобы он загружался один раз, и чтобы я всегда знал, где его искать.

Затем вы можете получить к нему доступ в таких моделях:

class MySuperAwesomeModel < ActiveRecord::Base
  acts_as_super_awesome
end
16
ответ дан 1 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: