2

私は Ruby と Rails (およびプログラミング!) が初めてで、モデルからその STI の子にプロパティを渡す慣用的な方法を理解しようとしています。

一般的なモデル「ドキュメント」と、それを継承するいくつかのモデルがあります — 「チュートリアル」を例に取りましょう。「アイコン」の文字列フィールドがあり、そこにアイコンのファイル名を保存しますが、フルパスは保存しません (レコードのデータを取得する詳細であるため、パスは各モデルまでにする必要があると思いますか?):

class Document < ActiveRecord::Base
  attr_accessible :title, :body, :icon

  @@asset_domain = "http://assets.example.com/"
  @@asset_path = "documents/"

  def icon
    @@asset_domain.to_s + @@asset_path.to_s + read_attribute(:icon).to_s
  end
end

これは私がサブクラスでやりたいことであり、サブクラスは適切な場所で「アイコン」(またはその他のアセット) を探します。

class Tutorial < Document
  attr_accessible :title, :body, :icon

  @@asset_path = "tutorials/"

  # Other tutorial-only stuff
end

クラス変数について読んで、上で書いたことが意図したとおりに機能しなかった理由を理解しましたが、Tutorial クラスで「asset_path」をオーバーライドする最良の方法は何ですか? モデルのインスタンスごとに値を変更する必要がないため、インスタンス変数を使用する必要はないと思います。どんなアイデアでも大歓迎です (たとえそれが再考を意味するとしても!)

4

2 に答える 2

4

パスを構築するために再利用できる定数値を作成しようとしているようです。クラス変数を使用する代わりに、定数を使用します。

配置の問題:

クラスで

およびそれを継承するクラスでのみ使用する必要がある場合Documentは、スタックの一番上に定数を定義します。

# document.rb
#
class Document < ActiveRecord::Base
  attr_accessible :title, :body, :icon

  ASSET_DOMAIN = "http://assets.example.com/"

end

これは、Document Tutorialおよびそれらを継承する他のオブジェクトでアクセスできます。

環境.rb

これがどこでも使用する値である場合、に定数を追加するのはどうenvironment.rbですか? そうすれば、配置したすべてのクラスで再定義することを覚えておく必要はありません。

# environment.rb
#
# other config info
#
ASSET_DOMAIN = "http://assets.example.com/"

そして、クラスに制約されずに、好きな場所にリンクを作成できます。

# documents.rb
#
icon_path = ASSET_DOMAIN + path_and_file

# tutorial.rb
#
icon_path = ASSET_DOMAIN + path_and_file

# non_document_model.rb
#
icon_path = ASSET_DOMAIN + path_and_file

これは論説かもしれませんが、ルビー主義者は@@. 時間と場所はありますが、やりたいことの種類については、定数を使用して、それを配置する必要がある場所を決定します。

于 2012-05-03T20:52:10.887 に答える
1

inから関数を単純にオーバーライドして(icon関数から継承しているため)、正しいパスを返すようにすることができます。DocumentTutorial

これは、オブジェクト指向プログラミングにおけるポリモーフィズムの典型的なケースです。例:

class Document
  attr_accessor :title, :body, :icon

  ASSET_DOMAIN = "http://assets.example.com/"

  def icon
    return ASSET_DOMAIN + "documents/" + "document_icon.png"
  end
end

class Tutorial < Document
  def icon
    return ASSET_DOMAIN + "tutorials/" + "tutorial_icon.png"
  end
end

d = Document.new
puts d.icon

i = Tutorial.new
puts i.icon

出力:

http://assets.example.com/documents/document_icon.png
http://assets.example.com/tutorials/tutorial_icon.png

Tutorialは のサブクラスであるためDocument、そのフィールドとメソッドの両方を継承することに注意してください。したがって:title:bodyと を:icon内部で再定義する必要はなくTutorialiconメソッドを再定義して目的の出力を得ることができます。この場合、めったに変化しない値を定数に格納することも賢明ASSET_DOMAINです。

于 2012-05-03T20:44:09.827 に答える