ruby on rails - generate - Ruby(Rails) ¿Delegar atributos en el método de otro modelo?
ruby on rails scaffold (4)
-EDITAR-
Después de leer sobre el método Delegado de la primera respuesta, mi pregunta es esta: ¿es posible delegar dos métodos diferentes a otro método único?
IE: Actualmente tengo: @ photo.attachment.file.url, y @ photo.attachment.height, y @ photo.attachment.width
Me gustaría poder acceder a todos estos a través de @ photo.file.url, @ photo.file.height, @ photo.file.width.
La razón de la sintaxis es que Attachment es un modelo que usa Paperclip para administrar archivos, Paperclip está generando el método .file (el modelo se llama Attachment, el modelo usa has_attached_file :file
Paperclip).
-PREGUNA ORIGINAL-
Me preguntaba sobre los métodos y atributos de asignación de alias en Ruby (creo que esta es una pregunta general de Ruby, aunque mi aplicación está en Rails 3):
Tengo dos modelos: Photo has_one Attachment.
El archivo adjunto tiene atributos de "altura" y "ancho", y un método de "archivo" (de Paperclip).
Entonces, por defecto, puedo acceder a los bits del modelo Adjunto de la siguiente manera:
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
Ahora, en mi clase de fotos he creado este método:
def file(*args)
attachment.file(*args)
end
Entonces, ahora puedo simplemente usar:
photo.file # returns file path
photo.file.url # returns file url (or variant url if you pass a style symbol)
Mi pregunta es, pude dirigir photo.attachment.file
a solo photo.file
, pero también puedo asignar la altura y el ancho a photo.file
, para que, por coherencia, pueda acceder a los atributos de altura y anchura a través de photo.file.height
y photo.file.width
?
¿Es tal cosa posible, y si es así, cómo se ve?
Así que lo que estás preguntando es que
photo.file --> photo.attachment.file
photo.file.url --> photo.attachment.file.url
photo.file.width --> photo.attachment.width
No puede resolver esto con los delegados, porque quiere que ese file
signifique cosas diferentes en función de lo que sigue a continuación. Para lograr esto, necesitarías volver a abrir el clip, lo cual no recomendaría (porque creo que la API es buena como es).
La única forma en que puedo pensar para resolver esto, es agregar eliminar el nivel de file
también. Al igual que:
photo.width --> photo.attachment.width
photo.file --> photo.attachment.file
photo.url --> photo.attachment.file.url
Esto se podría resolver utilizando un delegate
para cada uno de los métodos deseados.
Entonces tu escribes
class Photo
delegate :width, :height, :file, :to => :attachment
delegate :url, :to => :''attachment.file''
end
Espero que esto ayude.
Con Ruby liso puedes usar Forwardable :
require ''forwardable''
class RecordCollection
attr_accessor :records
extend Forwardable
def_delegator :@records, :[], :record_number
end
La forma más sencilla que se me ocurre es delegar el método url en el archivo adjunto al archivo:
class Attachment < ActiveRecord::Base
delegate :url, :to => :file
end
De esta manera puedes llamar a photo.attachment.url, photo.attachment.width, photo.attachment.height, que para mí parece bastante consistente. Opcionalmente, podría alias adjuntar a archivo: de esta manera obtendría los nombres de los métodos exactos que solicitó (photo.file.width, photo.file.url), pero no lo recomendaría, porque parece confuso "expediente").
class Photo < ActiveRecord::Base
def file
attachment
end
end
Puedes usar el método ''delegado'' de Rails. Echa un vistazo a mi respuesta para esta pregunta:
¿Cuál es una forma más parecida a Ruby de hacer este comando?