4

デバイス モデルには次の属性があります: name、version、および full_name

フルネームは名前 + バージョンです:

class Device < ActiveRecord::Base
  def prepare
    full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

私が次のことをするとき:

d = Device.new :name => "iPhone", :version => "4"
d.prepare
d.full_name # get nil

「full_name」属性に nil を取得します

「自己」を使用しているときは、次のように機能します。

class Device < ActiveRecord::Base
  def prepare
    self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

「準備」を行うと、「full_name」属性に「iPhone 4」が表示されます。

ここにいる何人かは、クラスメソッド内で「自己」を使用しないようにするのが良い方法だと私に言いました。しかし、これは問題を引き起こします。

問題は、「self」を使用しないと機能しないのはなぜですか?

4

3 に答える 3

14

こういう場合はselfを使わないといけないので、問題ないと思います。を使用している場合self、インタープリターは、オブジェクトの属性を参照していることを認識します。使用しない場合はself、メソッドの終了後にどこにも格納されない単なるローカル変数であることを意味します。これは通常の動作です。セッター メソッドとして使用することもできますself[:full_name]= ...が、この場合はあまり重要ではありません。

アップデート

@アントンAL

ゲッターメソッドは . なしで認識されるためself.です。

属性を使用しようとするとname、インタープリターは現在のメソッド内でローカル変数を探します。見つからない場合は、インスタンス属性を探します。例:

def your_method
  self.name = 'iPhone'
  puts name
  #iPhone
  name = 'iPod'
  puts name
  #iPod
  puts self.name
  #iPhone
end

そして、オブジェクト インスタンスの属性iPhoneに格納されます。メソッドが終了すると失われますnameiPod

于 2011-03-20T15:30:26.737 に答える
13

セッターを使用する場合は、使用する必要があります。そうしないと、Ruby が新しいローカル変数が定義されてselfいると解釈してしまうからです。full_name

selfゲッターの場合、 Ruby は最初にローカル変数full_nameを検索し、ローカル変数がない場合はfull_nameメソッドを検索しfull_nameてゲッターを取得するため、呼び出す必要はありません。ローカル変数が定義されている場合full_name、ローカル変数の値が返されます。

これは前の質問でよりよく説明されています

于 2011-03-20T15:46:11.460 に答える
0

これは、ActiveRecord が設計により動作する方法であるため、予期されたものです。任意の属性を設定する必要がある場合は、別の種類のオブジェクトを使用する必要があります。

たとえば、Ruby には次のようなライブラリがあります。

OpenStruct

これにより、任意のキーと値を割り当てることができるオブジェクトを作成できます。自己なしで属性から値を取得する場合は、インスタンス グローバル変数属性を持つクラス OpenStruct のインスタンスが提供されます。しかし、新しい属性を設定したい場合は、新しい属性を持つクラス OpenStruct の新しいインスタンスを作成します。self がないと、属性を持たない古い OpenStruct オブジェクトになり、エラーが発生します。

そのようなライブラリを使用してから、データベースに保存する必要がある場合にのみ、オブジェクトを対応する ActiveRecord インスタンスに変換することができます。

説明したように動作するように ActiveRecord をモデル化しようとしないでください。そのように動作するように設計されていないためです。

于 2018-11-06T10:27:30.850 に答える