Как расширить функциональность объекта ActiveRecord в Rails? - PullRequest
3 голосов
/ 29 июля 2011

У меня есть класс с именем Story, связанный с классом с именем User. У меня также есть класс под названием Parser, который расширяет Story с помощью возможностей анализа (например, нахождение существительных).

class User < ActiveRecord::Base
    has_many :stories
end

class Story < ActiveRecord::Base
    belongs_to :user
    attr_accessible :title, :content
end

class Parser < Story
    def find_nouns
        self.content.do_something
    end
end

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

User.first.stories.new(:title => 'Foo', :content => 'Bar')

Как бы мне этого добиться и все же элегантно связать запись с первой историей?

Что-то вроде этого:

User.first.stories.new(:title => 'Foo', :content => 'Bar').find_nouns

Проблема в том, что базовый класс не имеет доступа к методу find_nouns - он принадлежит StoryParser.

Ответы [ 2 ]

3 голосов
/ 29 июля 2011

Ваш класс Parser выглядит так, как будто он должен быть модулем, смешанным с классом или экземплярами Story, потому что это один из аспектов истории.

http://en.wikipedia.org/wiki/Aspect-oriented_programming

Вот модуль:

module Parser
  def find_nouns
    ...
  end
end

Смешайте это в классе с include:

class Story
  include Parser
end

Или смешайте его в случаях Story:

@user.stories.first.extend(Parser).find_nouns
0 голосов
/ 29 июля 2011

Не похоже на Парсер относится к Story , парсер должен быть своего собственного класса и иметь методы, которые получают Story или просто чистые строки и разбирать их, чтобы делать свою работу.

Истории не "извлекают" существительные из себя, поэтому парсеру не имеет смысла быть подклассом Истории.

story = Story.new(:content => 'some content')
parser = Parser.new
parser.find_nouns( story.content ) # would generate ['content']
...