Виртуальные атрибуты в плагине - PullRequest
0 голосов
/ 11 августа 2009

Мне нужна помощь с виртуальными атрибутами. Этот код работает нормально, но как мне использовать его внутри плагина. Цель состоит в том, чтобы добавить эти методы ко всем классам, которые используют плагин.

class Article < ActiveRecord::Base

  attr_accessor :title, :permalink

  def title
    if @title 
      @title
    elsif self.page
      self.page.title
    else 
      ""
    end
  end

  def permalink
    if @permalink
      @permalink
    elsif self.page
      self.page.permalink
    else
      ""
    end
  end
end

Спасибо

Ответы [ 3 ]

1 голос
/ 11 августа 2009

Вы можете запустить генератор плагинов, чтобы начать.

script/generate plugin acts_as_page

Затем вы можете добавить модуль, который определяет acts_as_page и распространяет его на все модели.

# in plugins/acts_as_page/lib/acts_as_page.rb
module ActsAsPage
  def acts_as_page
    # ...
  end
end

# in plugins/acts_as_page/init.rb
class ActiveRecord::Base
  extend ActsAsPage
end

Таким образом метод act_as_page доступен как метод класса для всех моделей, и вы можете определить любое поведение в нем. Вы могли бы сделать что-то вроде этого ...

module ActsAsPage
  def acts_as_page
    attr_writer :title, :permalink
    include Behavior
  end

  module Behavior
    def title
      # ...
    end

    def permalink
      # ...
    end
  end
end

А потом, когда вы вызываете acts_as_page в модели ...

class Article < ActiveRecord::Base
  acts_as_page
end

Он определит атрибуты и добавит методы. Если вам нужны более динамичные вещи (например, если вы хотите, чтобы метод acts_as_page принимал аргументы, изменяющие поведение), попробуйте решение, которое я представляю в в этом эпизоде ​​Railscasts .

0 голосов
/ 11 августа 2009

Создайте структуру модуля, такую ​​как YourPlugin::InstanceMethods, и включите в нее этот модуль следующим образом:

module YourPlugin
  module InstanceMethods
    # your methods
  end
end

ActiveRecord::Base.__send__(:include, YourPlugin::InstanceMethods)

Вы должны использовать __send__, чтобы сделать ваш код совместимым с Ruby 1.9. Строка __send__ обычно помещается в файл init.rb в корневом каталоге вашего плагина.

0 голосов
/ 11 августа 2009

Похоже, что вы хотите модуль для этого

# my_methods.rb 
module MyMethods
  def my_method_a
    "Hello"
  end
end

Вы хотите включить его в классы, для которых хотите его использовать.

class MyClass < ActiveRecord::Base
  include MyMethods
end

> m = MyClass.new
> m.my_method_a
=> "Hello!" 

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

...