web-dev-qa-db-ja.com

Ruby(Rails)属性を別のモデルのメソッドに委任しますか?

-編集-

最初の回答からデリゲートメソッドについて読んだ後、私の質問はこれです。2つの異なるメソッドを別の単一のメソッドに委任することは可能ですか。

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のエイリアスメソッドと属性について疑問に思っていました(私のアプリケーションはRuby 3にありますが、これは一般的なRailsの質問だと思います):

私は2つのモデルを持っています:写真has_one添付ファイル。

添付ファイルには、「height」属性と「width」属性、および「file」メソッド(Paperclipから)があります。

したがって、デフォルトでは、次のように添付ファイルモデルのビットにアクセスできます。

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.filephoto.fileだけに向けることができましたが、高さと幅をphoto.fileにマッピングして、一貫性を保つために、にアクセスできるようにすることもできます。 photo.file.heightおよびphoto.file.widthを介した高さと幅の属性?

そのようなことは可能ですか?もしそうなら、それはどのように見えますか?

19
Andrew

だからあなたが求めているのはそれです

photo.file       --> photo.attachment.file
photo.file.url   --> photo.attachment.file.url
photo.file.width --> photo.attachment.width

fileが次に続くことに基づいて異なることを意味するようにしたいので、デリゲートでこれを解決することはできません。これを実現するには、Paperclipを再度開く必要がありますが、これはお勧めしません(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

お役に立てれば。

53
nathanvda

Rails 'delegate'メソッドを使用できます。この質問に対する私の答えを見てください:

このコマンドを実行するRubyのような方法は何ですか?

5
monocle

頭に浮かぶ最も簡単な方法は、添付ファイルの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
1
psyho

プレーンRubyで使用できます 転送可能

require 'forwardable'

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