Создание помощника в модели ruby ​​для быстрого доступа - PullRequest
1 голос
/ 26 января 2012

У меня есть модель видео, которая содержит несколько различных закодированных версий видео. Каждая кодированная версия имеет одинаковые поля. Схема выглядит примерно так:

Videos:
 id: integer
 url: string
 version_mp4_id: integer
 version_mp4_encoding_status: string
 version_mp4_dimensions: string
 version_ogg_id: integer
 version_ogg_encoding_status: string
 version_ogg_dimensions: string

Теперь достаточно просто сказать v.version_mp4_id = 1 , но я пытался сделать это немного умнее, чтобы я мог обращаться с ними так, как если бы они были каждой своей сущностью, хотя все еще хранение всей информации в одной таблице.

Итак, я написал класс под названием VideoVersion , который является вложенным классом Video . Это выглядит так:

class VideoVersion
  attr_accessor :id, :url, :encoding_status, :dimensions

  def initialize(video, format)
    @video = video
    @format = format
    @id = @video.read_attribute("version_#{format}_id")
    @url = @video.read_attribute("version_#{format}_url")
    @dimensions = @video.read_attribute("version_#{format}_dimensions")
    @encoding_status = @video.read_attribute("version_#{format}_encoding_status")
  end

  def attributes
    return {
      "version_#{@format}_id" =>  @id,
      "version_#{@format}_url" =>  @url,
      "version_#{@format}_dimensions" =>  @dimensions,
      "version_#{@format}_encoding_status" =>  @encoding_status
    }
  end
  alias :attrs :attributes

  def save!
    @video.update_attributes(attributes)      
  end

end

и у меня есть три метода для класса видео, как это:

def version(format)
  raise UnsupportedFormat unless FORMATS.include?(format)
  return VideoVersion.new(self, format)
end

def mp4
  version('mp4')
end

def ogg
  version('ogg')
end

Это позволяет мне сказать v.mp4.id и заставить его вернуть нужную информацию. Это все хорошо и денди.

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

v = Video.find(1)
vv = VideoVersion.new(v, 'mp4')
puts vv.encoding_status
=> 'started'
v.version_mp4_encoding_status = 'finished'
puts vv.encoding_status
=> 'started'
v.mp4.encoding_status = 'pending'
puts v.version_mp4_encoding_status
=> 'finished'

Поскольку видео передается по значению, исходный объект не изменяется. Это довольно очевидно.

Короче говоря, я пытаюсь выяснить, есть ли лучший способ сделать ярлык без лишних хлопот и проблем. Метод отсутствует? Что-то другое? Или я просто ленивый и слишком усложняю свой код ...:)

Заранее спасибо!

1 Ответ

1 голос
/ 26 января 2012

Джереми, я не уверен, что полностью понимаю пару ваших методов, однако мне кажется, что вы можете свернуть все функциональные возможности вашего класса VideoVersion в свой класс Videos.Я исхожу из предположения, что ваша проблема - это скорее проблема «вложенного» класса.

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