Ruby (Rails) Делегирует атрибуты другого метода модели?
-Edit -
После прочтения метода Delegate из первого ответа, мой вопрос заключается в том, можно ли делегировать два разных метода другому одному методу.
IE: В настоящее время у меня есть: @photo.attachment.file.url и @photo.attachment.height и @photo.attachment.width
Я хотел бы иметь доступ ко всем этим через @photo.file.url, @photo.file.height, @photo.file.width.
Причиной синтаксиса является Attachment - модель, которая использует Paperclip для управления файлами, Paperclip генерирует метод .file(модель называется Attachment, модель использует Paperclip has_attached_file :file
).
-ООРИНАЛЬНЫЙ ВОПРОС -
Мне было интересно узнать о методах и атрибутах псевдонимов в Ruby (я думаю, что это общий рубиновый вопрос, хотя мое приложение находится в Rails 3):
У меня две модели: Photo has_one Attachment.
Вложение имеет атрибуты "высота" и "ширина", а также метод "файл" (из "Паперклипа" ).
Таким образом, по умолчанию я могу получить доступ к битам модели Attachment следующим образом:
photo.attachment.width # returns width in px
photo.attachment.height # returns height in px
photo.attachment.file # returns file path
photo.attachment.file.url #returns url for the default style variant of the image
photo.attachment.file.url(:style) #returns the url for a given style variant of the image
Теперь, в моем классе фотографии я создал этот метод:
def file(*args)
attachment.file(*args)
end
Итак, теперь я могу просто использовать:
photo.file # returns file path
photo.file.url # returns file url (or variant url if you pass a style symbol)
Мой вопрос: я смог направить photo.attachment.file
только на photo.file
, но могу ли я также сопоставить высоту и ширину с photo.file
, так что для согласованности я мог бы получить доступ к высоте и ширине атрибуты через photo.file.height
и photo.file.width
?
Возможно ли такое, и если да, то на что это похоже?
Ответы
Ответ 1
Так что вы спрашиваете, что
photo.file --> photo.attachment.file
photo.file.url --> photo.attachment.file.url
photo.file.width --> photo.attachment.width
Вы не можете решить это с помощью делегатов, потому что вы хотите, чтобы file
означало разные вещи, основываясь на следующем. Для этого вам нужно будет снова открыть скрепку, которую я бы не рекомендовал (потому что я считаю, что api хорошо, как есть).
Единственный способ, который я могу решить, это добавить и уровень file
. Например:
photo.width --> photo.attachment.width
photo.file --> photo.attachment.file
photo.url --> photo.attachment.file.url
Затем вы можете решить с помощью delegate
для каждого из требуемых методов.
Итак, вы пишете
class Photo
delegate :width, :height, :file, :to => :attachment
delegate :url, :to => :'attachment.file'
end
Надеюсь, что это поможет.
Ответ 2
Вы можете использовать метод делегирования Rails. Взгляните на мой ответ на этот вопрос:
Что такое Ruby-подобный способ выполнения этой команды?
Ответ 3
Простейшим способом, который приходит на ум, является делегирование метода url в приложении к файлу:
class Attachment < ActiveRecord::Base
delegate :url, :to => :file
end
Таким образом, вы можете вызвать photo.attachment.url, photo.attachment.width, photo.attachment.height, что для меня кажется довольно последовательным. Вы могли бы при желании добавить псевдоним в файл - таким образом, вы получили бы точные имена методов, которые вы попросили (photo.file.width, photo.file.url), но я бы не рекомендовал это, потому что это кажется запутанным (вызов вложения "файл" ).
class Photo < ActiveRecord::Base
def file
attachment
end
end