4

User で呼び出されるメソッド (属性) に基づいてメソッドを定義する Model クラスを作成しました (これは Model から継承されます)。問題は、define_method で定義されたメソッドをオーバーライドできず、super を呼び出して定義済みのメソッドに渡すことができないことです。これは、定義されたメソッドがモデルではなくユーザー自体に追加されるためだと思います。そのため、実際にはスーパークラス (つまりモデル) にメソッドがありません。

これを行う理由は、ほとんどの属性をデータベースに直接保存する必要があるためですが、パスワードなどの一部の属性には追加の処理が必要です。

class Model
  def self.attribute(name)
    define_method(name) do
      self
    end
  end  
end

class User < Model
  attribute :password
end

class User2 < Model
  attribute :password

  def password
    super
  end
end

@user = User.new
puts @user.password # => <User:0x00000100845540>

@user2 = User2.new
puts @user2.password
# define_super.rb:17:in `password': super: no superclass method 
# `password' for #<User2:0x00000100845578> (NoMethodError)
# from define_super.rb:25:in `<main>'

これを機能させるためにコードを変更する方法はありますか? 動的に作成されたメソッドをオーバーライドする方法が必要です。

4

3 に答える 3

11

でメソッドを定義しますsuperclass

class Model
  def self.attribute(name)
    superclass.send :define_method, name do
      self
    end
  end  
end
于 2010-01-03T13:50:54.630 に答える
3

Rails がこれに対処する方法は、属性を取得する方法が複数あるということです。これらの 1 つは (慣例により) オーバーライドされないため、定義済みのメソッドで使用できます。

# This method is never overridden, but also rarely used as a public method
def[](key)
  # Returns value of `key` attribute
end

# This is the effective default implementation of an attribute
def att1
  self[:att1]
end

# This shows how you can have custom logic but still access the underlying value
def att2
  self[:att2] unless self[:att2].empty?
end
于 2010-01-03T13:51:44.613 に答える