Подклассы activerecord и ведение подкласса после выборки из БД - PullRequest
3 голосов
/ 06 июля 2011

У меня есть модель ActiveRecord Media, которая должна хранить информацию с аналогичной структурой о различных типах носителей (Media::Book, Media::Movie, Media::Music). Однако каждый из этих подклассов имеет уникальные методы.

# TABLE medias
# string :title
# string :description
# integer :media_type

class Media < ActiveRecord::Base
end

class Media
  class Book < Media
    def reviews
      GoogleBooks.search(name).get_reviews
    end
  end
  class Movie < Media
    def reviews
      IMDB.search_movies(name).reviews
    end
  end
  class Music < Media
    def reviews
      Lastfm.search(name).comments
    end

    def music_video
      Youtube.search(name).first.embed_html
    end
  end
end

Это сработало бы, если бы я использовал Media::Book.new("Harry Potter").reviews, но я хочу иметь возможность использовать

Media.find("Harry Potter")
=> Media::Book

и

Media.find("Harry Potter").reviews

Я знаю, что для этого нужно использовать media_type, но я не уверен, есть ли лучший способ сделать это, чем переопределение каждого метода интерфейса базы данных ActiveRecord (User.medias, find, find_by_etc, where, order, limit, all) и замена каждого из возвращаемых значений.

1 Ответ

7 голосов
/ 06 июля 2011

для этого можно использовать функцию наследования отдельных таблиц ActiveRecords. Он использует другой столбец в вашей таблице моделей (по умолчанию это столбец с именем "type"), чтобы определить тип модели для каждой записи.

Просто добавьте столбец строкового типа в таблицу medias, и Rails сделает все за вас, когда найдет этот столбец в схеме базы данных. Если у вас все в порядке с AR, добавляющим тип в столбец media_type, вы также можете изменить столбец, используемый для наследования отдельных таблиц, с помощью метода класса set_inheritance_column.

class Media < ActiveRecord::Base
  set_inheritance_column :media_type
end

Тогда в этом столбце вы найдете имя класса соответствующего объекта с полным именем класса в пространстве. (например: «Media :: Book»). Тем не менее, вы не хотите изменять содержимое столбца типа (или любого столбца, который вы используете) вручную. ActiveRecord позаботится об этом сам.

Взгляните на http://api.rubyonrails.org/classes/ActiveRecord/Base.html и найдите "наследование одной таблицы" на этой странице для получения дополнительной информации

Edit: только что понял, что ваш столбец media_type является целым числом. Так что использование его для ИППП не сработает. Просто придерживайтесь столбца строкового типа, и пусть AR сделает все остальное за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...