Rails 4.2でイニシャライザを使用してメソッドをActiveRecordモデルに追加しようとしています。ただし、イニシャライザでクラスを再オープンするだけで、既存の属性アクセサが破損します。イニシャライザのクラスを再オープンすると、属性アクセサが破損する
モデルアプリ/モデル/ thing.rb:
class Thing < ActiveRecord::Base
end
移行DB /移行/ 20160914144414_create_things.rb:
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
t.integer :test_field
t.timestamps null: false
end
end
end
初期設定/初期化子/ thing.rb:
class Thing
def self.new_method
"hello"
end
end
テストファイル/ models/thing_test.rb:
require File.expand_path("../../test_helper", __FILE__)
class ThingTest < ActiveSupport::TestCase
test "the truth" do
thing = Thing.new
thing.test_field = 1
puts thing.new_method
end
end
私はここに私のテストを実行して、私が得るものです:
❯❯❯ rtest test/models/thing_test.rb
1) Error:
ThingTest#test_the_truth:
NoMethodError: undefined method `test_field=' for #<Thing:0x00000101464658>
test/models/thing_test.rb:6:in `block in <class:ThingTest>'
私はクラスにメソッドを追加するには、この代替構文を使用している場合は、それが動作:
Thing.class_eval do
def self.new_method
"hello"
end
end
私は「推測しますこのようにしてうれしいですが、クラスを再開するだけでは効果がないのはなぜですか。
私はイニシャライザでクラスを作成していません。再オープンしてメソッドを追加しようとしています。 Rubyが許可していることを理解している –
イニシャライザは最初に実行されません。イニシャライザの実行時にクラスが既に存在します。 –
ファイルの先頭にデバッガー文を置いています。デバッガでは 'Thing.superclass'をクエリでき、ActiveRecord :: Baseを取得します。私はThingのインスタンスを作成し、それにtest_fieldを呼び出します。 –