У меня есть модель видео, которая содержит несколько различных закодированных версий видео. Каждая кодированная версия имеет одинаковые поля. Схема выглядит примерно так:
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'
Поскольку видео передается по значению, исходный объект не изменяется. Это довольно очевидно.
Короче говоря, я пытаюсь выяснить, есть ли лучший способ сделать ярлык без лишних хлопот и проблем. Метод отсутствует? Что-то другое? Или я просто ленивый и слишком усложняю свой код ...:)
Заранее спасибо!