Ruby (Rails) 将属性委托给另一个模型的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4703357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ruby (Rails) Delegate attributes to another model's method?
提问by Andrew
-EDIT-
-编辑-
After reading about the Delegate method from the first answer, my question is this, is it possible to delegate two different methods to another single method.
从第一个答案中阅读了 Delegate 方法后,我的问题是,是否可以将两种不同的方法委托给另一种方法。
IE: I currently have: @photo.attachment.file.url, and @photo.attachment.height, and @photo.attachment.width
IE:我目前有:@photo.attachment.file.url、@photo.attachment.height 和@photo.attachment.width
I'd like to be able to access all of these via @photo.file.url, @photo.file.height, @photo.file.width.
我希望能够通过@photo.file.url、@photo.file.height、@photo.file.width 访问所有这些。
The reason for the syntax is Attachment is a model that uses Paperclip to manage files, Paperclip is generating the .file method (the model is called Attachment, the model uses Paperclip's has_attached_file :file).
语法的原因是Attachment是一个使用Paperclip管理文件的模型,Paperclip正在生成.file方法(该模型称为Attachment,模型使用Paperclip的has_attached_file :file)。
-ORIGINAL QUESTION-
-原始问题-
I was wondering about aliasing methods and attributes in Ruby (I think this is a general ruby question, although my application is in Rails 3):
我想知道 Ruby 中的别名方法和属性(我认为这是一个通用的 ruby 问题,尽管我的应用程序在 Rails 3 中):
I have two models: Photo has_one Attachment.
我有两个模型:照片 has_one 附件。
Attachment has "height" and "width" attributes, and a "file" method (from Paperclip).
附件具有“高度”和“宽度”属性,以及“文件”方法(来自 Paperclip)。
So by default I can access bits of the Attachment model like so:
所以默认情况下,我可以像这样访问附件模型的位:
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
Now, in my photo class I have created this method:
现在,在我的照片类中,我创建了这个方法:
def file(*args)
attachment.file(*args)
end
So, now I can simply use:
所以,现在我可以简单地使用:
photo.file # returns file path
photo.file.url # returns file url (or variant url if you pass a style symbol)
My question is, I was able to direct photo.attachment.fileto just photo.file, but can I also map height and width to photo.file, so that, for the sake of consistency, I could access the height and width attributes through photo.file.heightand photo.file.width?
我的问题是,我能够直接photo.attachment.file指向photo.file,但我也可以将高度和宽度映射到photo.file,以便为了一致性起见,我可以通过photo.file.height和访问高度和宽度属性photo.file.width?
Is such a thing possible, and if so what does it look like?
这样的事情可能吗,如果有的话,它看起来像什么?
回答by nathanvda
So what you are asking is that
所以你要问的是
photo.file --> photo.attachment.file
photo.file.url --> photo.attachment.file.url
photo.file.width --> photo.attachment.width
You can't solve this with delegates, because you want that fileto mean different things based on what follows next. To achieve this you would need to reopen paperclip, which i would not recommend (because i believe the api is good the way it is).
你不能用委托来解决这个问题,因为你希望file根据接下来的内容来代表不同的东西。要实现这一点,您需要重新打开回形针,我不推荐这样做(因为我相信 api 就这样很好)。
The only way i can think of to solve this, is to add eliminate the filelevel too. Like so:
我能想到的解决这个问题的唯一方法就是添加消除file级别。像这样:
photo.width --> photo.attachment.width
photo.file --> photo.attachment.file
photo.url --> photo.attachment.file.url
This you could then solve by using a delegatefor each of the wanted methods.
然后,您可以通过delegate对每个想要的方法使用 a来解决这个问题。
So you write
所以你写
class Photo
delegate :width, :height, :file, :to => :attachment
delegate :url, :to => :'attachment.file'
end
Hope this helps.
希望这可以帮助。
回答by monocle
You can use Rails 'delegate' method. Have a look at my answer for this question:
您可以使用 Rails 的“委托”方法。看看我对这个问题的回答:
回答by psyho
The simplest way that comes to mind is to delegate url method in attachment to file:
想到的最简单的方法是将附件中的 url 方法委托给文件:
class Attachment < ActiveRecord::Base
delegate :url, :to => :file
end
This way you can call photo.attachment.url, photo.attachment.width, photo.attachment.height, which for me seems pretty consistent. You could optionally alias attachment to file - this way you'd get the exact method names you asked for (photo.file.width, photo.file.url), but I would not recommend that, because it seems confusing (calling an attachment "file").
通过这种方式,您可以调用 photo.attachment.url、photo.attachment.width、photo.attachment.height,这对我来说似乎非常一致。您可以选择将附件作为文件的别名 - 这样您就可以获得您要求的确切方法名称(photo.file.width,photo.file.url),但我不建议这样做,因为它看起来令人困惑(调用附件“文件”)。
class Photo < ActiveRecord::Base
def file
attachment
end
end
回答by Damien Roche
With plain Ruby you can use Forwardable:
使用普通的 Ruby,您可以使用Forwardable:
require 'forwardable'
class RecordCollection
attr_accessor :records
extend Forwardable
def_delegator :@records, :[], :record_number
end

