Ruby(Rails)将属性委托给另一个模型的方法?

时间:2011-01-16 02:02:03

标签: ruby-on-rails ruby-on-rails-3 alias shortcut

- 编辑 -

从第一个答案中读到委托方法后,我的问题是,是否可以将两种不同的方法委托给另一种方法。

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)。

-ORIGINAL QUESTION -

我想知道Ruby中的别名方法和属性(我认为这是一个常见的ruby问题,尽管我的应用程序在Rails 3中):

我有两个模特:照片has_one附件。

附件具有“高度”和“宽度”属性,以及“文件”方法(来自Paperclip)。

所以默认情况下我可以像这样访问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.heightphoto.file.width

访问高度和宽度属性

这样的事情是否可能,如果是这样,它看起来像什么?

4 个答案:

答案 0 :(得分:53)

所以你要问的是

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

希望这有帮助。

答案 1 :(得分:5)

您可以使用Rails'委托'方法。看看我对这个问题的回答:

What is a more Ruby-like way of doing this command?

答案 2 :(得分:1)

最简单的方法是将附件中的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

答案 3 :(得分:0)

使用普通的Ruby,您可以使用Forwardable

require 'forwardable'

class RecordCollection
  attr_accessor :records
  extend Forwardable
  def_delegator :@records, :[], :record_number
end